Normalize line endings to LF via .gitattributes
Репозиторий хранил фронтенд в CRLF, а часть бэкенда — вперемешку, хотя CI и Docker-сборка работают под Linux. Прибиваем LF атрибутом `* text=auto eol=lf` и разово нормализуем дерево, чтобы форматтеры не переписывали файлы целиком на каждом прогоне. Коммит чисто механический: изменений содержимого нет, только концы строк. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9d1c6d2fc3
commit
0442056367
@@ -1,96 +1,96 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TeleWave.Application.Broadcast.Scheduling;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Programming.Planning;
|
||||
|
||||
namespace TeleWave.Infrastructure.Broadcast;
|
||||
|
||||
/// <summary>
|
||||
/// Периодически достраивает расписание каждого включённого канала до горизонта. Расширение хвоста —
|
||||
/// без удаления существующих записей, поэтому эфир не «дёргается».
|
||||
/// </summary>
|
||||
public sealed class SchedulingBackgroundService(
|
||||
IServiceScopeFactory scopeFactory,
|
||||
IOptions<SchedulerOptions> options,
|
||||
ILogger<SchedulingBackgroundService> logger
|
||||
) : BackgroundService
|
||||
{
|
||||
private readonly SchedulerOptions _options = options.Value;
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
// Небольшая задержка на старте — дать примениться миграциям/сидингу.
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var timer = new PeriodicTimer(
|
||||
TimeSpan.FromMinutes(Math.Max(1, _options.TickMinutes))
|
||||
);
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
await TickAsync(stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Ошибка тика планировщика");
|
||||
}
|
||||
} while (await timer.WaitForNextTickAsync(stoppingToken));
|
||||
}
|
||||
|
||||
private async Task TickAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await using var scope = scopeFactory.CreateAsyncScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<IAppDbContext>();
|
||||
var generator = scope.ServiceProvider.GetRequiredService<GridScheduleGenerator>();
|
||||
|
||||
// Эфир строит только шаблон сетки: канал без шаблона вещать не может и молча пропускается.
|
||||
var channelIds = await db
|
||||
.Channels.Where(c => c.IsEnabled && c.TemplateId != null)
|
||||
.Select(c => c.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
foreach (var channelId in channelIds)
|
||||
{
|
||||
var report = await generator.GenerateAsync(
|
||||
channelId,
|
||||
now,
|
||||
rebuildFuture: false,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
if (report.Added > 0)
|
||||
logger.LogInformation(
|
||||
"Канал {ChannelId}: добавлено {Count} записей расписания",
|
||||
channelId,
|
||||
report.Added
|
||||
);
|
||||
|
||||
foreach (var warning in report.Warnings)
|
||||
logger.LogWarning(
|
||||
"Канал {ChannelId}, слот {SlotId}: {Warning} — {Details}",
|
||||
channelId,
|
||||
warning.SlotId,
|
||||
warning.Kind,
|
||||
warning.Details
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TeleWave.Application.Broadcast.Scheduling;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Programming.Planning;
|
||||
|
||||
namespace TeleWave.Infrastructure.Broadcast;
|
||||
|
||||
/// <summary>
|
||||
/// Периодически достраивает расписание каждого включённого канала до горизонта. Расширение хвоста —
|
||||
/// без удаления существующих записей, поэтому эфир не «дёргается».
|
||||
/// </summary>
|
||||
public sealed class SchedulingBackgroundService(
|
||||
IServiceScopeFactory scopeFactory,
|
||||
IOptions<SchedulerOptions> options,
|
||||
ILogger<SchedulingBackgroundService> logger
|
||||
) : BackgroundService
|
||||
{
|
||||
private readonly SchedulerOptions _options = options.Value;
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
// Небольшая задержка на старте — дать примениться миграциям/сидингу.
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var timer = new PeriodicTimer(
|
||||
TimeSpan.FromMinutes(Math.Max(1, _options.TickMinutes))
|
||||
);
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
await TickAsync(stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Ошибка тика планировщика");
|
||||
}
|
||||
} while (await timer.WaitForNextTickAsync(stoppingToken));
|
||||
}
|
||||
|
||||
private async Task TickAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await using var scope = scopeFactory.CreateAsyncScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<IAppDbContext>();
|
||||
var generator = scope.ServiceProvider.GetRequiredService<GridScheduleGenerator>();
|
||||
|
||||
// Эфир строит только шаблон сетки: канал без шаблона вещать не может и молча пропускается.
|
||||
var channelIds = await db
|
||||
.Channels.Where(c => c.IsEnabled && c.TemplateId != null)
|
||||
.Select(c => c.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
foreach (var channelId in channelIds)
|
||||
{
|
||||
var report = await generator.GenerateAsync(
|
||||
channelId,
|
||||
now,
|
||||
rebuildFuture: false,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
if (report.Added > 0)
|
||||
logger.LogInformation(
|
||||
"Канал {ChannelId}: добавлено {Count} записей расписания",
|
||||
channelId,
|
||||
report.Added
|
||||
);
|
||||
|
||||
foreach (var warning in report.Warnings)
|
||||
logger.LogWarning(
|
||||
"Канал {ChannelId}, слот {SlotId}: {Warning} — {Details}",
|
||||
channelId,
|
||||
warning.SlotId,
|
||||
warning.Kind,
|
||||
warning.Details
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,168 +1,168 @@
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using TeleWave.Application.Broadcast.Bumpers;
|
||||
using TeleWave.Application.Broadcast.Scheduling;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Streaming;
|
||||
using TeleWave.Domain.Broadcast.Scheduling;
|
||||
using TeleWave.Infrastructure.Broadcast;
|
||||
using TeleWave.Infrastructure.Identity;
|
||||
using TeleWave.Infrastructure.Library;
|
||||
using TeleWave.Infrastructure.Media;
|
||||
using TeleWave.Infrastructure.Metadata;
|
||||
using TeleWave.Infrastructure.Persistence;
|
||||
using TeleWave.Infrastructure.Settings;
|
||||
using TeleWave.Infrastructure.Streaming;
|
||||
|
||||
namespace TeleWave.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// Регистрация сервисов инфраструктуры: EF Core (PostgreSQL), Identity/JWT-аутентификация.
|
||||
/// </summary>
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static IServiceCollection AddInfrastructure(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
services.AddDbContext<AppDbContext>(options =>
|
||||
options.UseNpgsql(
|
||||
configuration["ConnectionStrings:Default"]
|
||||
?? throw new InvalidOperationException(
|
||||
"Строка подключения 'ConnectionStrings:Default' не сконфигурирована."
|
||||
)
|
||||
)
|
||||
);
|
||||
services.AddScoped<IAppDbContext>(sp => sp.GetRequiredService<AppDbContext>());
|
||||
|
||||
services
|
||||
.AddIdentityCore<AppUser>(options =>
|
||||
{
|
||||
options.User.RequireUniqueEmail = false;
|
||||
options.Password.RequiredLength = 8;
|
||||
options.Password.RequireDigit = true;
|
||||
options.Password.RequireUppercase = true;
|
||||
options.Password.RequireNonAlphanumeric = false;
|
||||
options.Lockout.MaxFailedAccessAttempts = 5;
|
||||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
||||
options.Lockout.AllowedForNewUsers = true;
|
||||
})
|
||||
.AddRoles<AppRole>()
|
||||
.AddEntityFrameworkStores<AppDbContext>()
|
||||
.AddSignInManager()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName));
|
||||
services.Configure<AdminSeedOptions>(
|
||||
configuration.GetSection(AdminSeedOptions.SectionName)
|
||||
);
|
||||
|
||||
var jwtOptions =
|
||||
configuration.GetSection(JwtOptions.SectionName).Get<JwtOptions>()
|
||||
?? throw new InvalidOperationException("Секция конфигурации 'Jwt' не задана.");
|
||||
|
||||
// Fail-fast на подписывающем ключе: этот же ключ подписывает и JWT, и stream-токены
|
||||
// (StreamTokenService), поэтому placeholder/короткий ключ из appsettings.json = полный обход
|
||||
// авторизации (можно сфорджить admin-JWT). Лучше не стартовать вовсе, чем стартовать уязвимым.
|
||||
// HMAC-SHA256 требует ключ не короче размера хеша (32 байта), иначе он ослаблен нулевым паддингом.
|
||||
if (Encoding.UTF8.GetByteCount(jwtOptions.SigningKey) < 32)
|
||||
throw new InvalidOperationException(
|
||||
"Jwt:SigningKey должен быть не короче 32 байт. Задайте криптостойкий секрет через конфигурацию/переменную окружения Jwt__SigningKey."
|
||||
);
|
||||
if (jwtOptions.SigningKey.Contains("change-me", StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
"Jwt:SigningKey использует значение-заглушку из appsettings.json. Переопределите его криптостойким секретом (Jwt__SigningKey)."
|
||||
);
|
||||
|
||||
services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = jwtOptions.Issuer,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = jwtOptions.Audience,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(jwtOptions.SigningKey)
|
||||
),
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.FromSeconds(30),
|
||||
};
|
||||
});
|
||||
|
||||
services.AddAuthorization();
|
||||
|
||||
services.AddScoped<IIdentityService, IdentityService>();
|
||||
services.AddScoped<IJwtTokenService, JwtTokenService>();
|
||||
services.AddScoped<IRefreshTokenService, RefreshTokenService>();
|
||||
services.AddScoped<IRoleService, RoleService>();
|
||||
services.AddScoped<ICurrentUser, CurrentUser>();
|
||||
services.AddScoped<ISiteSettings, SiteSettings>();
|
||||
services.AddScoped<DbInitializer>();
|
||||
services.AddScoped<GenreSeeder>();
|
||||
|
||||
AddMedia(services, configuration);
|
||||
AddBroadcast(services, configuration);
|
||||
AddMetadata(services, configuration);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>Метаданные шоу/серий: провайдеры TMDb/OMDb, резолвер, локальное хранилище картинок.</summary>
|
||||
private static void AddMetadata(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<MetadataOptions>(configuration.GetSection(MetadataOptions.SectionName));
|
||||
services.AddHttpClient("metadata", client => client.Timeout = TimeSpan.FromSeconds(15));
|
||||
services.AddSingleton<IMetadataProvider, TmdbMetadataProvider>();
|
||||
services.AddSingleton<IMetadataProvider, OmdbMetadataProvider>();
|
||||
services.AddSingleton<IMetadataProviderResolver, MetadataProviderResolver>();
|
||||
}
|
||||
|
||||
/// <summary>Планировщик расписания: генератор, источник случайности и фоновый сервис горизонта.</summary>
|
||||
private static void AddBroadcast(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<SchedulerOptions>(
|
||||
configuration.GetSection(SchedulerOptions.SectionName)
|
||||
);
|
||||
services.Configure<StreamingOptions>(
|
||||
configuration.GetSection(StreamingOptions.SectionName)
|
||||
);
|
||||
services.Configure<BumperOptions>(configuration.GetSection(BumperOptions.SectionName));
|
||||
|
||||
services.AddSingleton<IRandomSource, SystemRandomSource>();
|
||||
services.AddSingleton<StreamTokenService>();
|
||||
services.AddSingleton<IBumperRenderer, FfmpegBumperRenderer>();
|
||||
services.AddHostedService<SchedulingBackgroundService>();
|
||||
services.AddHostedService<MaintenanceBackgroundService>();
|
||||
}
|
||||
|
||||
/// <summary>Хранилище медиа, обработка ffmpeg, очередь и фоновые сервисы (очередь + inbox-сканер).</summary>
|
||||
private static void AddMedia(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<StorageOptions>(configuration.GetSection(StorageOptions.SectionName));
|
||||
services.Configure<MediaOptions>(configuration.GetSection(MediaOptions.SectionName));
|
||||
|
||||
services.AddSingleton<MediaPathResolver>();
|
||||
services.AddSingleton<IMediaStorage, FileSystemMediaStorage>();
|
||||
services.AddSingleton<IBumperTemplateStorage, BumperTemplateStorage>();
|
||||
services.AddSingleton<IImageStore, ImageStore>();
|
||||
services.AddSingleton<IImageDownloader, ImageDownloader>();
|
||||
services.AddSingleton<IAudioProbe, FfprobeAudioProbe>();
|
||||
services.AddSingleton<IMediaProcessor, FfmpegMediaProcessor>();
|
||||
services.AddSingleton<IMediaProcessingQueue, MediaProcessingQueue>();
|
||||
services.AddSingleton<IBumperRenderQueue, BumperRenderQueue>();
|
||||
|
||||
services.AddHostedService<MediaProcessingBackgroundService>();
|
||||
services.AddHostedService<InboxScannerBackgroundService>();
|
||||
services.AddHostedService<BumperRenderBackgroundService>();
|
||||
}
|
||||
}
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using TeleWave.Application.Broadcast.Bumpers;
|
||||
using TeleWave.Application.Broadcast.Scheduling;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Streaming;
|
||||
using TeleWave.Domain.Broadcast.Scheduling;
|
||||
using TeleWave.Infrastructure.Broadcast;
|
||||
using TeleWave.Infrastructure.Identity;
|
||||
using TeleWave.Infrastructure.Library;
|
||||
using TeleWave.Infrastructure.Media;
|
||||
using TeleWave.Infrastructure.Metadata;
|
||||
using TeleWave.Infrastructure.Persistence;
|
||||
using TeleWave.Infrastructure.Settings;
|
||||
using TeleWave.Infrastructure.Streaming;
|
||||
|
||||
namespace TeleWave.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// Регистрация сервисов инфраструктуры: EF Core (PostgreSQL), Identity/JWT-аутентификация.
|
||||
/// </summary>
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static IServiceCollection AddInfrastructure(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
services.AddDbContext<AppDbContext>(options =>
|
||||
options.UseNpgsql(
|
||||
configuration["ConnectionStrings:Default"]
|
||||
?? throw new InvalidOperationException(
|
||||
"Строка подключения 'ConnectionStrings:Default' не сконфигурирована."
|
||||
)
|
||||
)
|
||||
);
|
||||
services.AddScoped<IAppDbContext>(sp => sp.GetRequiredService<AppDbContext>());
|
||||
|
||||
services
|
||||
.AddIdentityCore<AppUser>(options =>
|
||||
{
|
||||
options.User.RequireUniqueEmail = false;
|
||||
options.Password.RequiredLength = 8;
|
||||
options.Password.RequireDigit = true;
|
||||
options.Password.RequireUppercase = true;
|
||||
options.Password.RequireNonAlphanumeric = false;
|
||||
options.Lockout.MaxFailedAccessAttempts = 5;
|
||||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
||||
options.Lockout.AllowedForNewUsers = true;
|
||||
})
|
||||
.AddRoles<AppRole>()
|
||||
.AddEntityFrameworkStores<AppDbContext>()
|
||||
.AddSignInManager()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName));
|
||||
services.Configure<AdminSeedOptions>(
|
||||
configuration.GetSection(AdminSeedOptions.SectionName)
|
||||
);
|
||||
|
||||
var jwtOptions =
|
||||
configuration.GetSection(JwtOptions.SectionName).Get<JwtOptions>()
|
||||
?? throw new InvalidOperationException("Секция конфигурации 'Jwt' не задана.");
|
||||
|
||||
// Fail-fast на подписывающем ключе: этот же ключ подписывает и JWT, и stream-токены
|
||||
// (StreamTokenService), поэтому placeholder/короткий ключ из appsettings.json = полный обход
|
||||
// авторизации (можно сфорджить admin-JWT). Лучше не стартовать вовсе, чем стартовать уязвимым.
|
||||
// HMAC-SHA256 требует ключ не короче размера хеша (32 байта), иначе он ослаблен нулевым паддингом.
|
||||
if (Encoding.UTF8.GetByteCount(jwtOptions.SigningKey) < 32)
|
||||
throw new InvalidOperationException(
|
||||
"Jwt:SigningKey должен быть не короче 32 байт. Задайте криптостойкий секрет через конфигурацию/переменную окружения Jwt__SigningKey."
|
||||
);
|
||||
if (jwtOptions.SigningKey.Contains("change-me", StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
"Jwt:SigningKey использует значение-заглушку из appsettings.json. Переопределите его криптостойким секретом (Jwt__SigningKey)."
|
||||
);
|
||||
|
||||
services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = jwtOptions.Issuer,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = jwtOptions.Audience,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(jwtOptions.SigningKey)
|
||||
),
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.FromSeconds(30),
|
||||
};
|
||||
});
|
||||
|
||||
services.AddAuthorization();
|
||||
|
||||
services.AddScoped<IIdentityService, IdentityService>();
|
||||
services.AddScoped<IJwtTokenService, JwtTokenService>();
|
||||
services.AddScoped<IRefreshTokenService, RefreshTokenService>();
|
||||
services.AddScoped<IRoleService, RoleService>();
|
||||
services.AddScoped<ICurrentUser, CurrentUser>();
|
||||
services.AddScoped<ISiteSettings, SiteSettings>();
|
||||
services.AddScoped<DbInitializer>();
|
||||
services.AddScoped<GenreSeeder>();
|
||||
|
||||
AddMedia(services, configuration);
|
||||
AddBroadcast(services, configuration);
|
||||
AddMetadata(services, configuration);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>Метаданные шоу/серий: провайдеры TMDb/OMDb, резолвер, локальное хранилище картинок.</summary>
|
||||
private static void AddMetadata(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<MetadataOptions>(configuration.GetSection(MetadataOptions.SectionName));
|
||||
services.AddHttpClient("metadata", client => client.Timeout = TimeSpan.FromSeconds(15));
|
||||
services.AddSingleton<IMetadataProvider, TmdbMetadataProvider>();
|
||||
services.AddSingleton<IMetadataProvider, OmdbMetadataProvider>();
|
||||
services.AddSingleton<IMetadataProviderResolver, MetadataProviderResolver>();
|
||||
}
|
||||
|
||||
/// <summary>Планировщик расписания: генератор, источник случайности и фоновый сервис горизонта.</summary>
|
||||
private static void AddBroadcast(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<SchedulerOptions>(
|
||||
configuration.GetSection(SchedulerOptions.SectionName)
|
||||
);
|
||||
services.Configure<StreamingOptions>(
|
||||
configuration.GetSection(StreamingOptions.SectionName)
|
||||
);
|
||||
services.Configure<BumperOptions>(configuration.GetSection(BumperOptions.SectionName));
|
||||
|
||||
services.AddSingleton<IRandomSource, SystemRandomSource>();
|
||||
services.AddSingleton<StreamTokenService>();
|
||||
services.AddSingleton<IBumperRenderer, FfmpegBumperRenderer>();
|
||||
services.AddHostedService<SchedulingBackgroundService>();
|
||||
services.AddHostedService<MaintenanceBackgroundService>();
|
||||
}
|
||||
|
||||
/// <summary>Хранилище медиа, обработка ffmpeg, очередь и фоновые сервисы (очередь + inbox-сканер).</summary>
|
||||
private static void AddMedia(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<StorageOptions>(configuration.GetSection(StorageOptions.SectionName));
|
||||
services.Configure<MediaOptions>(configuration.GetSection(MediaOptions.SectionName));
|
||||
|
||||
services.AddSingleton<MediaPathResolver>();
|
||||
services.AddSingleton<IMediaStorage, FileSystemMediaStorage>();
|
||||
services.AddSingleton<IBumperTemplateStorage, BumperTemplateStorage>();
|
||||
services.AddSingleton<IImageStore, ImageStore>();
|
||||
services.AddSingleton<IImageDownloader, ImageDownloader>();
|
||||
services.AddSingleton<IAudioProbe, FfprobeAudioProbe>();
|
||||
services.AddSingleton<IMediaProcessor, FfmpegMediaProcessor>();
|
||||
services.AddSingleton<IMediaProcessingQueue, MediaProcessingQueue>();
|
||||
services.AddSingleton<IBumperRenderQueue, BumperRenderQueue>();
|
||||
|
||||
services.AddHostedService<MediaProcessingBackgroundService>();
|
||||
services.AddHostedService<InboxScannerBackgroundService>();
|
||||
services.AddHostedService<BumperRenderBackgroundService>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,171 +1,171 @@
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Media;
|
||||
using TeleWave.Domain.Media;
|
||||
|
||||
namespace TeleWave.Infrastructure.Media;
|
||||
|
||||
/// <summary>Файловая реализация <see cref="IMediaStorage"/> поверх <see cref="MediaPathResolver"/>.</summary>
|
||||
public sealed class FileSystemMediaStorage(MediaPathResolver paths) : IMediaStorage
|
||||
{
|
||||
private const int CopyBufferSize = 1024 * 1024;
|
||||
|
||||
public long GetAvailableFreeSpaceBytes()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DriveInfo(paths.AssetsDir).AvailableFreeSpace;
|
||||
}
|
||||
catch (Exception ex) when (ex is ArgumentException or IOException)
|
||||
{
|
||||
// Не блокируем загрузку, если ФС не отдаёт метрику (например экзотическая точка монтирования).
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> SaveUploadAsync(
|
||||
Stream content,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
Directory.CreateDirectory(paths.UploadsDir);
|
||||
var token = Guid.NewGuid().ToString("N") + extension.ToLowerInvariant();
|
||||
var path = paths.UploadPath(token);
|
||||
|
||||
await using var file = new FileStream(
|
||||
path,
|
||||
FileMode.CreateNew,
|
||||
FileAccess.Write,
|
||||
FileShare.None,
|
||||
CopyBufferSize,
|
||||
useAsync: true
|
||||
);
|
||||
await content.CopyToAsync(file, CopyBufferSize, cancellationToken);
|
||||
return token;
|
||||
}
|
||||
|
||||
public Task DeleteUploadAsync(string uploadToken, CancellationToken cancellationToken)
|
||||
{
|
||||
var path = paths.UploadPath(uploadToken);
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public IReadOnlyList<IMediaStorage.ManualInboxFile> ListManualInbox(int max)
|
||||
{
|
||||
if (!Directory.Exists(paths.ManualDir))
|
||||
return [];
|
||||
|
||||
return Directory
|
||||
.EnumerateFiles(paths.ManualDir, "*", SearchOption.AllDirectories)
|
||||
.Take(Math.Max(1, max))
|
||||
.Select(path => new FileInfo(path))
|
||||
.Where(file => file.Exists)
|
||||
.Select(file => new IMediaStorage.ManualInboxFile(
|
||||
// Разделитель нормализуем: путь уезжает в URL и обратно приходит строкой запроса.
|
||||
Path.GetRelativePath(paths.ManualDir, file.FullName).Replace('\\', '/'),
|
||||
file.Name,
|
||||
file.Length
|
||||
))
|
||||
.OrderBy(f => f.RelativePath, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Task CleanupManualLeftoversAsync(
|
||||
string relativePath,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var path = paths.ManualPath(relativePath);
|
||||
var directory = Path.GetDirectoryName(path);
|
||||
if (directory is null || !Directory.Exists(directory))
|
||||
return Task.CompletedTask;
|
||||
|
||||
// Спутник — файл, чьё имя начинается с имени забранного (без расширения) и точки:
|
||||
// так ловятся и «Серия.srt», и «Серия.ru.srt». Видеофайлы исключены намеренно —
|
||||
// «Серия.Extended.mkv» это не мусор, а другой материал.
|
||||
// Отбор — своим сравнением, а не маской поиска: в имени файла на Linux законно встречается
|
||||
// «*», и маска захватила бы чужие файлы. Код удаляет — он обязан быть буквальным.
|
||||
var prefix = Path.GetFileNameWithoutExtension(path) + ".";
|
||||
foreach (var sibling in Directory.EnumerateFiles(directory))
|
||||
{
|
||||
var name = Path.GetFileName(sibling);
|
||||
if (!name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
if (MediaFormats.IsAllowed(name))
|
||||
continue;
|
||||
try
|
||||
{
|
||||
File.Delete(sibling);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Файл занят или уже удалён — не повод валить импорт целиком.
|
||||
}
|
||||
}
|
||||
|
||||
// Опустевший подкаталог тоже мусор. Корень manual/ не трогаем: он нужен всегда.
|
||||
if (
|
||||
!string.Equals(directory, paths.ManualDir, StringComparison.Ordinal)
|
||||
&& !Directory.EnumerateFileSystemEntries(directory).Any()
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(directory);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Каталог занят — оставим как есть.
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task PromoteToOriginalAsync(
|
||||
MediaSource source,
|
||||
string sourceToken,
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var sourcePath = source switch
|
||||
{
|
||||
MediaSource.Inbox => paths.InboxPath(sourceToken),
|
||||
MediaSource.ManualInbox => paths.ManualPath(sourceToken),
|
||||
_ => paths.UploadPath(sourceToken),
|
||||
};
|
||||
|
||||
if (!File.Exists(sourcePath))
|
||||
throw new FileNotFoundException("Исходный файл не найден в хранилище.", sourcePath);
|
||||
|
||||
Directory.CreateDirectory(paths.OriginalsDir);
|
||||
var destination = paths.OriginalPath(assetId, extension);
|
||||
File.Move(sourcePath, destination, overwrite: true);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task DeleteAssetArtifactsAsync(
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
) =>
|
||||
// Каталог сегментов удаляется рекурсивно (может быть много .ts) — офлоадим с вызывающего потока
|
||||
// (запрос/фоновый сервис), чтобы не блокировать его на время файлового I/O.
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
var original = paths.OriginalPath(assetId, extension);
|
||||
if (File.Exists(original))
|
||||
File.Delete(original);
|
||||
|
||||
var assetDir = paths.AssetDir(assetId);
|
||||
if (Directory.Exists(assetDir))
|
||||
Directory.Delete(assetDir, recursive: true);
|
||||
},
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Media;
|
||||
using TeleWave.Domain.Media;
|
||||
|
||||
namespace TeleWave.Infrastructure.Media;
|
||||
|
||||
/// <summary>Файловая реализация <see cref="IMediaStorage"/> поверх <see cref="MediaPathResolver"/>.</summary>
|
||||
public sealed class FileSystemMediaStorage(MediaPathResolver paths) : IMediaStorage
|
||||
{
|
||||
private const int CopyBufferSize = 1024 * 1024;
|
||||
|
||||
public long GetAvailableFreeSpaceBytes()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DriveInfo(paths.AssetsDir).AvailableFreeSpace;
|
||||
}
|
||||
catch (Exception ex) when (ex is ArgumentException or IOException)
|
||||
{
|
||||
// Не блокируем загрузку, если ФС не отдаёт метрику (например экзотическая точка монтирования).
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> SaveUploadAsync(
|
||||
Stream content,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
Directory.CreateDirectory(paths.UploadsDir);
|
||||
var token = Guid.NewGuid().ToString("N") + extension.ToLowerInvariant();
|
||||
var path = paths.UploadPath(token);
|
||||
|
||||
await using var file = new FileStream(
|
||||
path,
|
||||
FileMode.CreateNew,
|
||||
FileAccess.Write,
|
||||
FileShare.None,
|
||||
CopyBufferSize,
|
||||
useAsync: true
|
||||
);
|
||||
await content.CopyToAsync(file, CopyBufferSize, cancellationToken);
|
||||
return token;
|
||||
}
|
||||
|
||||
public Task DeleteUploadAsync(string uploadToken, CancellationToken cancellationToken)
|
||||
{
|
||||
var path = paths.UploadPath(uploadToken);
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public IReadOnlyList<IMediaStorage.ManualInboxFile> ListManualInbox(int max)
|
||||
{
|
||||
if (!Directory.Exists(paths.ManualDir))
|
||||
return [];
|
||||
|
||||
return Directory
|
||||
.EnumerateFiles(paths.ManualDir, "*", SearchOption.AllDirectories)
|
||||
.Take(Math.Max(1, max))
|
||||
.Select(path => new FileInfo(path))
|
||||
.Where(file => file.Exists)
|
||||
.Select(file => new IMediaStorage.ManualInboxFile(
|
||||
// Разделитель нормализуем: путь уезжает в URL и обратно приходит строкой запроса.
|
||||
Path.GetRelativePath(paths.ManualDir, file.FullName).Replace('\\', '/'),
|
||||
file.Name,
|
||||
file.Length
|
||||
))
|
||||
.OrderBy(f => f.RelativePath, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Task CleanupManualLeftoversAsync(
|
||||
string relativePath,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var path = paths.ManualPath(relativePath);
|
||||
var directory = Path.GetDirectoryName(path);
|
||||
if (directory is null || !Directory.Exists(directory))
|
||||
return Task.CompletedTask;
|
||||
|
||||
// Спутник — файл, чьё имя начинается с имени забранного (без расширения) и точки:
|
||||
// так ловятся и «Серия.srt», и «Серия.ru.srt». Видеофайлы исключены намеренно —
|
||||
// «Серия.Extended.mkv» это не мусор, а другой материал.
|
||||
// Отбор — своим сравнением, а не маской поиска: в имени файла на Linux законно встречается
|
||||
// «*», и маска захватила бы чужие файлы. Код удаляет — он обязан быть буквальным.
|
||||
var prefix = Path.GetFileNameWithoutExtension(path) + ".";
|
||||
foreach (var sibling in Directory.EnumerateFiles(directory))
|
||||
{
|
||||
var name = Path.GetFileName(sibling);
|
||||
if (!name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
if (MediaFormats.IsAllowed(name))
|
||||
continue;
|
||||
try
|
||||
{
|
||||
File.Delete(sibling);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Файл занят или уже удалён — не повод валить импорт целиком.
|
||||
}
|
||||
}
|
||||
|
||||
// Опустевший подкаталог тоже мусор. Корень manual/ не трогаем: он нужен всегда.
|
||||
if (
|
||||
!string.Equals(directory, paths.ManualDir, StringComparison.Ordinal)
|
||||
&& !Directory.EnumerateFileSystemEntries(directory).Any()
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(directory);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Каталог занят — оставим как есть.
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task PromoteToOriginalAsync(
|
||||
MediaSource source,
|
||||
string sourceToken,
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var sourcePath = source switch
|
||||
{
|
||||
MediaSource.Inbox => paths.InboxPath(sourceToken),
|
||||
MediaSource.ManualInbox => paths.ManualPath(sourceToken),
|
||||
_ => paths.UploadPath(sourceToken),
|
||||
};
|
||||
|
||||
if (!File.Exists(sourcePath))
|
||||
throw new FileNotFoundException("Исходный файл не найден в хранилище.", sourcePath);
|
||||
|
||||
Directory.CreateDirectory(paths.OriginalsDir);
|
||||
var destination = paths.OriginalPath(assetId, extension);
|
||||
File.Move(sourcePath, destination, overwrite: true);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task DeleteAssetArtifactsAsync(
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
) =>
|
||||
// Каталог сегментов удаляется рекурсивно (может быть много .ts) — офлоадим с вызывающего потока
|
||||
// (запрос/фоновый сервис), чтобы не блокировать его на время файлового I/O.
|
||||
Task.Run(
|
||||
() =>
|
||||
{
|
||||
var original = paths.OriginalPath(assetId, extension);
|
||||
if (File.Exists(original))
|
||||
File.Delete(original);
|
||||
|
||||
var assetDir = paths.AssetDir(assetId);
|
||||
if (Directory.Exists(assetDir))
|
||||
Directory.Delete(assetDir, recursive: true);
|
||||
},
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace TeleWave.Infrastructure.Media;
|
||||
|
||||
/// <summary>
|
||||
/// Единая точка резолва путей хранилища + защита от path traversal. Любой путь, собранный из
|
||||
/// внешних данных (имя загруженного файла, имя из inbox/), проверяется на нахождение внутри корня.
|
||||
/// </summary>
|
||||
public sealed class MediaPathResolver
|
||||
{
|
||||
private readonly string _root;
|
||||
|
||||
public MediaPathResolver(IOptions<StorageOptions> options)
|
||||
{
|
||||
_root = Path.GetFullPath(options.Value.RootPath);
|
||||
InboxDir = Path.Combine(_root, "inbox");
|
||||
ManualDir = Path.Combine(_root, "manual");
|
||||
UploadsDir = Path.Combine(_root, "uploads");
|
||||
OriginalsDir = Path.Combine(_root, "originals");
|
||||
AssetsDir = Path.Combine(_root, "assets");
|
||||
BumpersDir = Path.Combine(_root, "bumpers");
|
||||
ImagesDir = Path.Combine(_root, "images");
|
||||
}
|
||||
|
||||
public string InboxDir { get; }
|
||||
|
||||
/// <summary>Ручной inbox: сканером не разбирается, файлы забирает админ из UI сразу в шоу.</summary>
|
||||
public string ManualDir { get; }
|
||||
public string UploadsDir { get; }
|
||||
public string OriginalsDir { get; }
|
||||
public string AssetsDir { get; }
|
||||
|
||||
/// <summary>Сырые файлы шаблонов заставок (фон/музыка) по каналам — не режутся на HLS.</summary>
|
||||
public string BumpersDir { get; }
|
||||
|
||||
/// <summary>Общий реестр изображений (галерея): файлы images/{imageId}{ext}.</summary>
|
||||
public string ImagesDir { get; }
|
||||
|
||||
public void EnsureDirectories()
|
||||
{
|
||||
Directory.CreateDirectory(InboxDir);
|
||||
Directory.CreateDirectory(ManualDir);
|
||||
Directory.CreateDirectory(UploadsDir);
|
||||
Directory.CreateDirectory(OriginalsDir);
|
||||
Directory.CreateDirectory(AssetsDir);
|
||||
Directory.CreateDirectory(BumpersDir);
|
||||
Directory.CreateDirectory(ImagesDir);
|
||||
}
|
||||
|
||||
public string BumperTemplateDir(Guid templateId) =>
|
||||
EnsureWithinRoot(Path.Combine(BumpersDir, templateId.ToString("N")));
|
||||
|
||||
/// <summary>Путь к файлу блока заставки (kind — «audio»/«background», extension — с точкой).</summary>
|
||||
public string BumperTemplateFilePath(Guid templateId, string kind, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(BumpersDir, templateId.ToString("N"), kind + extension));
|
||||
|
||||
/// <summary>Путь к файлу изображения общего реестра (extension — с точкой).</summary>
|
||||
public string ImagePath(Guid imageId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(ImagesDir, imageId.ToString("N") + extension));
|
||||
|
||||
public string OriginalPath(Guid assetId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(OriginalsDir, assetId.ToString("N") + extension));
|
||||
|
||||
public string AssetDir(Guid assetId) =>
|
||||
EnsureWithinRoot(Path.Combine(AssetsDir, assetId.ToString("N")));
|
||||
|
||||
public static string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}";
|
||||
|
||||
/// <summary>Путь к файлу сегмента внутри каталога ассета (имя файла проверяется на traversal).</summary>
|
||||
public string SegmentPath(Guid assetId, string fileName)
|
||||
{
|
||||
var assetDir = AssetDir(assetId);
|
||||
return EnsureWithin(assetDir, Path.Combine(assetDir, fileName));
|
||||
}
|
||||
|
||||
/// <summary>Резолвит имя файла внутри uploads/ (токен загрузки), проверяя выход за пределы каталога.</summary>
|
||||
public string UploadPath(string token) =>
|
||||
EnsureWithin(UploadsDir, Path.Combine(UploadsDir, token));
|
||||
|
||||
/// <summary>Резолвит имя файла внутри inbox/, проверяя выход за пределы каталога.</summary>
|
||||
public string InboxPath(string fileName) =>
|
||||
EnsureWithin(InboxDir, Path.Combine(InboxDir, fileName));
|
||||
|
||||
/// <summary>
|
||||
/// Резолвит путь внутри manual/. Путь относительный и может содержать подкаталоги — качалки
|
||||
/// раскладывают файлы по папкам, — поэтому проверка на выход за пределы каталога здесь
|
||||
/// обязательна: строка приходит из запроса.
|
||||
/// </summary>
|
||||
public string ManualPath(string relativePath) =>
|
||||
EnsureWithin(ManualDir, Path.Combine(ManualDir, relativePath));
|
||||
|
||||
private string EnsureWithinRoot(string candidate) => EnsureWithin(_root, candidate);
|
||||
|
||||
private static string EnsureWithin(string baseDir, string candidate)
|
||||
{
|
||||
var full = Path.GetFullPath(candidate);
|
||||
var normalizedBase = baseDir.EndsWith(Path.DirectorySeparatorChar)
|
||||
? baseDir
|
||||
: baseDir + Path.DirectorySeparatorChar;
|
||||
|
||||
if (
|
||||
!full.StartsWith(normalizedBase, StringComparison.Ordinal)
|
||||
&& !string.Equals(full, baseDir, StringComparison.Ordinal)
|
||||
)
|
||||
throw new UnauthorizedAccessException(
|
||||
$"Путь '{candidate}' выходит за пределы каталога хранилища."
|
||||
);
|
||||
|
||||
return full;
|
||||
}
|
||||
}
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace TeleWave.Infrastructure.Media;
|
||||
|
||||
/// <summary>
|
||||
/// Единая точка резолва путей хранилища + защита от path traversal. Любой путь, собранный из
|
||||
/// внешних данных (имя загруженного файла, имя из inbox/), проверяется на нахождение внутри корня.
|
||||
/// </summary>
|
||||
public sealed class MediaPathResolver
|
||||
{
|
||||
private readonly string _root;
|
||||
|
||||
public MediaPathResolver(IOptions<StorageOptions> options)
|
||||
{
|
||||
_root = Path.GetFullPath(options.Value.RootPath);
|
||||
InboxDir = Path.Combine(_root, "inbox");
|
||||
ManualDir = Path.Combine(_root, "manual");
|
||||
UploadsDir = Path.Combine(_root, "uploads");
|
||||
OriginalsDir = Path.Combine(_root, "originals");
|
||||
AssetsDir = Path.Combine(_root, "assets");
|
||||
BumpersDir = Path.Combine(_root, "bumpers");
|
||||
ImagesDir = Path.Combine(_root, "images");
|
||||
}
|
||||
|
||||
public string InboxDir { get; }
|
||||
|
||||
/// <summary>Ручной inbox: сканером не разбирается, файлы забирает админ из UI сразу в шоу.</summary>
|
||||
public string ManualDir { get; }
|
||||
public string UploadsDir { get; }
|
||||
public string OriginalsDir { get; }
|
||||
public string AssetsDir { get; }
|
||||
|
||||
/// <summary>Сырые файлы шаблонов заставок (фон/музыка) по каналам — не режутся на HLS.</summary>
|
||||
public string BumpersDir { get; }
|
||||
|
||||
/// <summary>Общий реестр изображений (галерея): файлы images/{imageId}{ext}.</summary>
|
||||
public string ImagesDir { get; }
|
||||
|
||||
public void EnsureDirectories()
|
||||
{
|
||||
Directory.CreateDirectory(InboxDir);
|
||||
Directory.CreateDirectory(ManualDir);
|
||||
Directory.CreateDirectory(UploadsDir);
|
||||
Directory.CreateDirectory(OriginalsDir);
|
||||
Directory.CreateDirectory(AssetsDir);
|
||||
Directory.CreateDirectory(BumpersDir);
|
||||
Directory.CreateDirectory(ImagesDir);
|
||||
}
|
||||
|
||||
public string BumperTemplateDir(Guid templateId) =>
|
||||
EnsureWithinRoot(Path.Combine(BumpersDir, templateId.ToString("N")));
|
||||
|
||||
/// <summary>Путь к файлу блока заставки (kind — «audio»/«background», extension — с точкой).</summary>
|
||||
public string BumperTemplateFilePath(Guid templateId, string kind, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(BumpersDir, templateId.ToString("N"), kind + extension));
|
||||
|
||||
/// <summary>Путь к файлу изображения общего реестра (extension — с точкой).</summary>
|
||||
public string ImagePath(Guid imageId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(ImagesDir, imageId.ToString("N") + extension));
|
||||
|
||||
public string OriginalPath(Guid assetId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(OriginalsDir, assetId.ToString("N") + extension));
|
||||
|
||||
public string AssetDir(Guid assetId) =>
|
||||
EnsureWithinRoot(Path.Combine(AssetsDir, assetId.ToString("N")));
|
||||
|
||||
public static string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}";
|
||||
|
||||
/// <summary>Путь к файлу сегмента внутри каталога ассета (имя файла проверяется на traversal).</summary>
|
||||
public string SegmentPath(Guid assetId, string fileName)
|
||||
{
|
||||
var assetDir = AssetDir(assetId);
|
||||
return EnsureWithin(assetDir, Path.Combine(assetDir, fileName));
|
||||
}
|
||||
|
||||
/// <summary>Резолвит имя файла внутри uploads/ (токен загрузки), проверяя выход за пределы каталога.</summary>
|
||||
public string UploadPath(string token) =>
|
||||
EnsureWithin(UploadsDir, Path.Combine(UploadsDir, token));
|
||||
|
||||
/// <summary>Резолвит имя файла внутри inbox/, проверяя выход за пределы каталога.</summary>
|
||||
public string InboxPath(string fileName) =>
|
||||
EnsureWithin(InboxDir, Path.Combine(InboxDir, fileName));
|
||||
|
||||
/// <summary>
|
||||
/// Резолвит путь внутри manual/. Путь относительный и может содержать подкаталоги — качалки
|
||||
/// раскладывают файлы по папкам, — поэтому проверка на выход за пределы каталога здесь
|
||||
/// обязательна: строка приходит из запроса.
|
||||
/// </summary>
|
||||
public string ManualPath(string relativePath) =>
|
||||
EnsureWithin(ManualDir, Path.Combine(ManualDir, relativePath));
|
||||
|
||||
private string EnsureWithinRoot(string candidate) => EnsureWithin(_root, candidate);
|
||||
|
||||
private static string EnsureWithin(string baseDir, string candidate)
|
||||
{
|
||||
var full = Path.GetFullPath(candidate);
|
||||
var normalizedBase = baseDir.EndsWith(Path.DirectorySeparatorChar)
|
||||
? baseDir
|
||||
: baseDir + Path.DirectorySeparatorChar;
|
||||
|
||||
if (
|
||||
!full.StartsWith(normalizedBase, StringComparison.Ordinal)
|
||||
&& !string.Equals(full, baseDir, StringComparison.Ordinal)
|
||||
)
|
||||
throw new UnauthorizedAccessException(
|
||||
$"Путь '{candidate}' выходит за пределы каталога хранилища."
|
||||
);
|
||||
|
||||
return full;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,330 +1,330 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsBlocked = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
UserName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedUserName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
Email = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedEmail = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
PasswordHash = table.Column<string>(type: "text", nullable: true),
|
||||
SecurityStamp = table.Column<string>(type: "text", nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumber = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
AccessFailedCount = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RefreshTokens",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TokenHash = table.Column<string>(type: "text", nullable: false),
|
||||
ExpiresAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
RevokedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
ReplacedByTokenHash = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RefreshTokens", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoleClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table
|
||||
.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation(
|
||||
"Npgsql:ValueGenerationStrategy",
|
||||
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn
|
||||
),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table
|
||||
.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation(
|
||||
"Npgsql:ValueGenerationStrategy",
|
||||
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn
|
||||
),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserLogins",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderKey = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey(
|
||||
"PK_AspNetUserLogins",
|
||||
x => new { x.LoginProvider, x.ProviderKey }
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserRoles",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserTokens",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey(
|
||||
"PK_AspNetUserTokens",
|
||||
x => new
|
||||
{
|
||||
x.UserId,
|
||||
x.LoginProvider,
|
||||
x.Name,
|
||||
}
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetRoleClaims_RoleId",
|
||||
table: "AspNetRoleClaims",
|
||||
column: "RoleId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
table: "AspNetRoles",
|
||||
column: "NormalizedName",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserClaims_UserId",
|
||||
table: "AspNetUserClaims",
|
||||
column: "UserId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserLogins_UserId",
|
||||
table: "AspNetUserLogins",
|
||||
column: "UserId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserRoles_RoleId",
|
||||
table: "AspNetUserRoles",
|
||||
column: "RoleId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedEmail"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedUserName",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RefreshTokens_TokenHash",
|
||||
table: "RefreshTokens",
|
||||
column: "TokenHash",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RefreshTokens_UserId",
|
||||
table: "RefreshTokens",
|
||||
column: "UserId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "AspNetRoleClaims");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserClaims");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserLogins");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserRoles");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserTokens");
|
||||
|
||||
migrationBuilder.DropTable(name: "RefreshTokens");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetRoles");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUsers");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsBlocked = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
UserName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedUserName = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
Email = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
NormalizedEmail = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
PasswordHash = table.Column<string>(type: "text", nullable: true),
|
||||
SecurityStamp = table.Column<string>(type: "text", nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumber = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
AccessFailedCount = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RefreshTokens",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TokenHash = table.Column<string>(type: "text", nullable: false),
|
||||
ExpiresAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
RevokedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
ReplacedByTokenHash = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RefreshTokens", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoleClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table
|
||||
.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation(
|
||||
"Npgsql:ValueGenerationStrategy",
|
||||
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn
|
||||
),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table
|
||||
.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation(
|
||||
"Npgsql:ValueGenerationStrategy",
|
||||
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn
|
||||
),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserLogins",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderKey = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey(
|
||||
"PK_AspNetUserLogins",
|
||||
x => new { x.LoginProvider, x.ProviderKey }
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserRoles",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserTokens",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "text", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey(
|
||||
"PK_AspNetUserTokens",
|
||||
x => new
|
||||
{
|
||||
x.UserId,
|
||||
x.LoginProvider,
|
||||
x.Name,
|
||||
}
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetRoleClaims_RoleId",
|
||||
table: "AspNetRoleClaims",
|
||||
column: "RoleId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
table: "AspNetRoles",
|
||||
column: "NormalizedName",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserClaims_UserId",
|
||||
table: "AspNetUserClaims",
|
||||
column: "UserId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserLogins_UserId",
|
||||
table: "AspNetUserLogins",
|
||||
column: "UserId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserRoles_RoleId",
|
||||
table: "AspNetUserRoles",
|
||||
column: "RoleId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedEmail"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedUserName",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RefreshTokens_TokenHash",
|
||||
table: "RefreshTokens",
|
||||
column: "TokenHash",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RefreshTokens_UserId",
|
||||
table: "RefreshTokens",
|
||||
column: "UserId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "AspNetRoleClaims");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserClaims");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserLogins");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserRoles");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUserTokens");
|
||||
|
||||
migrationBuilder.DropTable(name: "RefreshTokens");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetRoles");
|
||||
|
||||
migrationBuilder.DropTable(name: "AspNetUsers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,90 +1,90 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddMediaAssets : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MediaAssets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
OriginalFileName = table.Column<string>(
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: false
|
||||
),
|
||||
OriginalExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: false
|
||||
),
|
||||
Source = table.Column<int>(type: "integer", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
Duration = table.Column<TimeSpan>(type: "interval", nullable: true),
|
||||
SegmentSeconds = table.Column<int>(type: "integer", nullable: true),
|
||||
SegmentCount = table.Column<int>(type: "integer", nullable: true),
|
||||
Width = table.Column<int>(type: "integer", nullable: true),
|
||||
Height = table.Column<int>(type: "integer", nullable: true),
|
||||
VideoCodec = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: true
|
||||
),
|
||||
AudioCodec = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: true
|
||||
),
|
||||
RelativePath = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
ErrorMessage = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
UpdatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MediaAssets", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAssets_CreatedAt",
|
||||
table: "MediaAssets",
|
||||
column: "CreatedAt"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAssets_Status",
|
||||
table: "MediaAssets",
|
||||
column: "Status"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "MediaAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddMediaAssets : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MediaAssets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
OriginalFileName = table.Column<string>(
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: false
|
||||
),
|
||||
OriginalExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: false
|
||||
),
|
||||
Source = table.Column<int>(type: "integer", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
Duration = table.Column<TimeSpan>(type: "interval", nullable: true),
|
||||
SegmentSeconds = table.Column<int>(type: "integer", nullable: true),
|
||||
SegmentCount = table.Column<int>(type: "integer", nullable: true),
|
||||
Width = table.Column<int>(type: "integer", nullable: true),
|
||||
Height = table.Column<int>(type: "integer", nullable: true),
|
||||
VideoCodec = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: true
|
||||
),
|
||||
AudioCodec = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: true
|
||||
),
|
||||
RelativePath = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
),
|
||||
ErrorMessage = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
UpdatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MediaAssets", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAssets_CreatedAt",
|
||||
table: "MediaAssets",
|
||||
column: "CreatedAt"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MediaAssets_Status",
|
||||
table: "MediaAssets",
|
||||
column: "Status"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "MediaAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+308
-308
@@ -1,308 +1,308 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBroadcastAndLibrary : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Channels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Slug = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
EpochUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
AdInsertion = table.Column<int>(type: "integer", nullable: false),
|
||||
AdsPerBreak = table.Column<int>(type: "integer", nullable: false),
|
||||
FillerAssetId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
NextAdIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Channels", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ScheduleEntries",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
EpisodeIndex = table.Column<int>(type: "integer", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ScheduleEntries", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Shows",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Shows", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelAd",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelAd", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelAd_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
NextEpisodeIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShow_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProgrammingOverride",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Mode = table.Column<int>(type: "integer", nullable: false),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProgrammingOverride", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProgrammingOverride_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShowEpisode",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShowEpisode", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowEpisode_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OverrideShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProgrammingOverrideId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OverrideShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OverrideShow_ProgrammingOverride_ProgrammingOverrideId",
|
||||
column: x => x.ProgrammingOverrideId,
|
||||
principalTable: "ProgrammingOverride",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelAd_ChannelId_Position",
|
||||
table: "ChannelAd",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_Slug",
|
||||
table: "Channels",
|
||||
column: "Slug",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShow_ChannelId_ShowId",
|
||||
table: "ChannelShow",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OverrideShow_ProgrammingOverrideId",
|
||||
table: "OverrideShow",
|
||||
column: "ProgrammingOverrideId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProgrammingOverride_ChannelId_StartsAtUtc_EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc", "EndsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_EndsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "EndsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_StartsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowEpisode_MediaAssetId",
|
||||
table: "ShowEpisode",
|
||||
column: "MediaAssetId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowEpisode_ShowId_Position",
|
||||
table: "ShowEpisode",
|
||||
columns: new[] { "ShowId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelAd");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "OverrideShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropTable(name: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropTable(name: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropTable(name: "Shows");
|
||||
|
||||
migrationBuilder.DropTable(name: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBroadcastAndLibrary : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Channels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Slug = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
EpochUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
AdInsertion = table.Column<int>(type: "integer", nullable: false),
|
||||
AdsPerBreak = table.Column<int>(type: "integer", nullable: false),
|
||||
FillerAssetId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
NextAdIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Channels", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ScheduleEntries",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
EpisodeIndex = table.Column<int>(type: "integer", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ScheduleEntries", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Shows",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Shows", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelAd",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelAd", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelAd_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
NextEpisodeIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShow_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProgrammingOverride",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Mode = table.Column<int>(type: "integer", nullable: false),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProgrammingOverride", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProgrammingOverride_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShowEpisode",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShowEpisode", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowEpisode_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OverrideShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProgrammingOverrideId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OverrideShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OverrideShow_ProgrammingOverride_ProgrammingOverrideId",
|
||||
column: x => x.ProgrammingOverrideId,
|
||||
principalTable: "ProgrammingOverride",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelAd_ChannelId_Position",
|
||||
table: "ChannelAd",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_Slug",
|
||||
table: "Channels",
|
||||
column: "Slug",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShow_ChannelId_ShowId",
|
||||
table: "ChannelShow",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OverrideShow_ProgrammingOverrideId",
|
||||
table: "OverrideShow",
|
||||
column: "ProgrammingOverrideId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProgrammingOverride_ChannelId_StartsAtUtc_EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc", "EndsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_EndsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "EndsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_StartsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowEpisode_MediaAssetId",
|
||||
table: "ShowEpisode",
|
||||
column: "MediaAssetId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowEpisode_ShowId_Position",
|
||||
table: "ShowEpisode",
|
||||
columns: new[] { "ShowId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelAd");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "OverrideShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropTable(name: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropTable(name: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropTable(name: "Shows");
|
||||
|
||||
migrationBuilder.DropTable(name: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBumpers : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumpersEnabled",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperAssets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
FromShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ToShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Signature = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperAssets", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperAssets_FromShowId_ToShowId_Signature",
|
||||
table: "BumperAssets",
|
||||
columns: new[] { "FromShowId", "ToShowId", "Signature" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumpersEnabled", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddBumpers : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumpersEnabled",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperAssets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
FromShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ToShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Signature = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperAssets", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperAssets_FromShowId_ToShowId_Signature",
|
||||
table: "BumperAssets",
|
||||
columns: new[] { "FromShowId", "ToShowId", "Signature" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumpersEnabled", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+118
-118
@@ -1,118 +1,118 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelBumperSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperAccentColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x38bdf8"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x0b1020"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor2",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x1e293b"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperDurationSeconds",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 8
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperFont",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMinIntervalMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNextLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "ДАЛЕЕ"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNowLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "СЕЙЧАС"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumperOnlyBetweenDifferentShows",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperTextColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "white"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "BumperAccentColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor2", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperDurationSeconds", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperFont", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMinIntervalMinutes", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNextLabel", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNowLabel", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperOnlyBetweenDifferentShows", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperTextColor", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelBumperSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperAccentColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x38bdf8"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x0b1020"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor2",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "0x1e293b"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperDurationSeconds",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 8
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperFont",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMinIntervalMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNextLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "ДАЛЕЕ"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNowLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "СЕЙЧАС"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumperOnlyBetweenDifferentShows",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperTextColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "white"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "BumperAccentColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor2", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperDurationSeconds", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperFont", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMinIntervalMinutes", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNextLabel", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNowLabel", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperOnlyBetweenDifferentShows", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperTextColor", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+97
-97
@@ -1,97 +1,97 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperFilesAndJingles : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMode",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperMusicExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperRevision",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextJingleIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelJingle",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelJingle", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelJingle_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelJingle_ChannelId_Position",
|
||||
table: "ChannelJingle",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelJingle");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMode", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMusicExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperRevision", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextJingleIndex", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperFilesAndJingles : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMode",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperMusicExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperRevision",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextJingleIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelJingle",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelJingle", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelJingle_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelJingle_ChannelId_Position",
|
||||
table: "ChannelJingle",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelJingle");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMode", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMusicExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperRevision", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextJingleIndex", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AppSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AppSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Key = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Value = table.Column<string>(
|
||||
type: "character varying(1024)",
|
||||
maxLength: 1024,
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AppSettings", x => x.Key);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "AppSettings");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AppSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AppSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Key = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Value = table.Column<string>(
|
||||
type: "character varying(1024)",
|
||||
maxLength: 1024,
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AppSettings", x => x.Key);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "AppSettings");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,57 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowMetadata : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MetadataExternalId",
|
||||
table: "Shows",
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MetadataProvider",
|
||||
table: "Shows",
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PosterPath",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Year",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "MetadataExternalId", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "MetadataProvider", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "PosterPath", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Year", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowMetadata : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MetadataExternalId",
|
||||
table: "Shows",
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MetadataProvider",
|
||||
table: "Shows",
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PosterPath",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Year",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "MetadataExternalId", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "MetadataProvider", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "PosterPath", table: "Shows");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Year", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +1,76 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EpisodeMetadata : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateOnly>(
|
||||
name: "AirDate",
|
||||
table: "ShowEpisode",
|
||||
type: "date",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Episode",
|
||||
table: "ShowEpisode",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Overview",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(4096)",
|
||||
maxLength: 4096,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Season",
|
||||
table: "ShowEpisode",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "StillPath",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "AirDate", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Episode", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Overview", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Season", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "StillPath", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Title", table: "ShowEpisode");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EpisodeMetadata : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateOnly>(
|
||||
name: "AirDate",
|
||||
table: "ShowEpisode",
|
||||
type: "date",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Episode",
|
||||
table: "ShowEpisode",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Overview",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(4096)",
|
||||
maxLength: 4096,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Season",
|
||||
table: "ShowEpisode",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "StillPath",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "AirDate", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Episode", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Overview", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Season", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "StillPath", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Title", table: "ShowEpisode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+246
-246
@@ -1,246 +1,246 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperTemplates : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelJingle");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperAccentColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor2", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperDurationSeconds", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMode", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMusicExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperTextColor", table: "Channels");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "NextJingleIndex",
|
||||
table: "Channels",
|
||||
newName: "NextBumperIndex"
|
||||
);
|
||||
|
||||
// Ревизия файлов уехала на блоки заставок — старый счётчик не переносим, стратегия по
|
||||
// умолчанию Rotation (0).
|
||||
migrationBuilder.DropColumn(name: "BumperRevision", table: "Channels");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperSelection",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperTemplate",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundColor2 = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
AccentColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
TextColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundImageExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
),
|
||||
AudioExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
),
|
||||
AudioDurationSeconds = table.Column<double>(
|
||||
type: "double precision",
|
||||
nullable: true
|
||||
),
|
||||
Revision = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperTemplate", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BumperTemplate_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperTemplate_ChannelId_Position",
|
||||
table: "BumperTemplate",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
// Каждому существующему каналу — дефолтный блок заставки (Position 0, без звука/фона).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
INSERT INTO "BumperTemplate"
|
||||
("Id", "ChannelId", "Position", "Name", "BackgroundColor", "BackgroundColor2",
|
||||
"AccentColor", "TextColor", "Revision", "CreatedAt")
|
||||
SELECT gen_random_uuid(), c."Id", 0, 'Заставка 1', '0x0b1020', '0x1e293b',
|
||||
'0x38bdf8', 'white', 0, now()
|
||||
FROM "Channels" c;
|
||||
"""
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperTemplate");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "NextBumperIndex",
|
||||
table: "Channels",
|
||||
newName: "NextJingleIndex"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperSelection", table: "Channels");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperRevision",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperAccentColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor2",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperDurationSeconds",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMode",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperMusicExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperTextColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelJingle",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelJingle", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelJingle_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelJingle_ChannelId_Position",
|
||||
table: "ChannelJingle",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperTemplates : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelJingle");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperAccentColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundColor2", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperBackgroundExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperDurationSeconds", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMode", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMusicExtension", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperTextColor", table: "Channels");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "NextJingleIndex",
|
||||
table: "Channels",
|
||||
newName: "NextBumperIndex"
|
||||
);
|
||||
|
||||
// Ревизия файлов уехала на блоки заставок — старый счётчик не переносим, стратегия по
|
||||
// умолчанию Rotation (0).
|
||||
migrationBuilder.DropColumn(name: "BumperRevision", table: "Channels");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperSelection",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperTemplate",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundColor2 = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
AccentColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
TextColor = table.Column<string>(
|
||||
type: "character varying(32)",
|
||||
maxLength: 32,
|
||||
nullable: false
|
||||
),
|
||||
BackgroundImageExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
),
|
||||
AudioExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
),
|
||||
AudioDurationSeconds = table.Column<double>(
|
||||
type: "double precision",
|
||||
nullable: true
|
||||
),
|
||||
Revision = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperTemplate", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BumperTemplate_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperTemplate_ChannelId_Position",
|
||||
table: "BumperTemplate",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
// Каждому существующему каналу — дефолтный блок заставки (Position 0, без звука/фона).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
INSERT INTO "BumperTemplate"
|
||||
("Id", "ChannelId", "Position", "Name", "BackgroundColor", "BackgroundColor2",
|
||||
"AccentColor", "TextColor", "Revision", "CreatedAt")
|
||||
SELECT gen_random_uuid(), c."Id", 0, 'Заставка 1', '0x0b1020', '0x1e293b',
|
||||
'0x38bdf8', 'white', 0, now()
|
||||
FROM "Channels" c;
|
||||
"""
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperTemplate");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "NextBumperIndex",
|
||||
table: "Channels",
|
||||
newName: "NextJingleIndex"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperSelection", table: "Channels");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperRevision",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperAccentColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundColor2",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperBackgroundExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperDurationSeconds",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMode",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperMusicExtension",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperTextColor",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelJingle",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelJingle", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelJingle_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelJingle_ChannelId_Position",
|
||||
table: "ChannelJingle",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowOriginalName : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "OriginalName", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowOriginalName : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "text",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "OriginalName", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ImageRegistry : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Images",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Category = table.Column<int>(type: "integer", nullable: false),
|
||||
FileExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: false
|
||||
),
|
||||
OriginalFileName = table.Column<string>(
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Images", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Images_Category_CreatedAt",
|
||||
table: "Images",
|
||||
columns: new[] { "Category", "CreatedAt" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "Images");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ImageRegistry : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Images",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Category = table.Column<int>(type: "integer", nullable: false),
|
||||
FileExtension = table.Column<string>(
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: false
|
||||
),
|
||||
OriginalFileName = table.Column<string>(
|
||||
type: "character varying(512)",
|
||||
maxLength: 512,
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Images", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Images_Category_CreatedAt",
|
||||
table: "Images",
|
||||
columns: new[] { "Category", "CreatedAt" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "Images");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowPosterImage : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PosterImageId",
|
||||
table: "Shows",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Переносим существующие постеры шоу в общий реестр изображений: на каждый постер —
|
||||
// запись Images (Category=1 ShowPoster) с расширением из старого пути; файлы перекладывает
|
||||
// startup-шаг RelocateLegacyImagesAsync. Затем удаляем колонку PosterPath.
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "PosterPath" FROM "Shows" WHERE "PosterPath" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 1, lower(coalesce(substring(r."PosterPath" from '\.[^.]*$'), '.jpg')), 'poster', now());
|
||||
UPDATE "Shows" SET "PosterImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "PosterPath", table: "Shows");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "PosterImageId", table: "Shows");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(256)",
|
||||
oldMaxLength: 256,
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PosterPath",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowPosterImage : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PosterImageId",
|
||||
table: "Shows",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Переносим существующие постеры шоу в общий реестр изображений: на каждый постер —
|
||||
// запись Images (Category=1 ShowPoster) с расширением из старого пути; файлы перекладывает
|
||||
// startup-шаг RelocateLegacyImagesAsync. Затем удаляем колонку PosterPath.
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "PosterPath" FROM "Shows" WHERE "PosterPath" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 1, lower(coalesce(substring(r."PosterPath" from '\.[^.]*$'), '.jpg')), 'poster', now());
|
||||
UPDATE "Shows" SET "PosterImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "PosterPath", table: "Shows");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "PosterImageId", table: "Shows");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "OriginalName",
|
||||
table: "Shows",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(256)",
|
||||
oldMaxLength: 256,
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PosterPath",
|
||||
table: "Shows",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+89
-89
@@ -1,89 +1,89 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EpisodeStillAndBumperBgImages : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "StillImageId",
|
||||
table: "ShowEpisode",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BackgroundImageId",
|
||||
table: "BumperTemplate",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Кадры серий → реестр (Category=2 EpisodeStill); файлы перекладывает RelocateLegacyImagesAsync.
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "StillPath" FROM "ShowEpisode" WHERE "StillPath" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 2, lower(coalesce(substring(r."StillPath" from '\.[^.]*$'), '.jpg')), 'still', now());
|
||||
UPDATE "ShowEpisode" SET "StillImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
// Фоны блоков заставок → реестр (Category=3 BumperBackground).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "BackgroundImageExtension" FROM "BumperTemplate" WHERE "BackgroundImageExtension" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 3, lower(r."BackgroundImageExtension"), 'background', now());
|
||||
UPDATE "BumperTemplate" SET "BackgroundImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "StillPath", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BackgroundImageExtension", table: "BumperTemplate");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "StillImageId", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BackgroundImageId", table: "BumperTemplate");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "StillPath",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BackgroundImageExtension",
|
||||
table: "BumperTemplate",
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EpisodeStillAndBumperBgImages : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "StillImageId",
|
||||
table: "ShowEpisode",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BackgroundImageId",
|
||||
table: "BumperTemplate",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Кадры серий → реестр (Category=2 EpisodeStill); файлы перекладывает RelocateLegacyImagesAsync.
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "StillPath" FROM "ShowEpisode" WHERE "StillPath" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 2, lower(coalesce(substring(r."StillPath" from '\.[^.]*$'), '.jpg')), 'still', now());
|
||||
UPDATE "ShowEpisode" SET "StillImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
// Фоны блоков заставок → реестр (Category=3 BumperBackground).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD; img uuid;
|
||||
BEGIN
|
||||
FOR r IN SELECT "Id", "BackgroundImageExtension" FROM "BumperTemplate" WHERE "BackgroundImageExtension" IS NOT NULL LOOP
|
||||
img := gen_random_uuid();
|
||||
INSERT INTO "Images" ("Id", "Category", "FileExtension", "OriginalFileName", "CreatedAt")
|
||||
VALUES (img, 3, lower(r."BackgroundImageExtension"), 'background', now());
|
||||
UPDATE "BumperTemplate" SET "BackgroundImageId" = img WHERE "Id" = r."Id";
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "StillPath", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BackgroundImageExtension", table: "BumperTemplate");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "StillImageId", table: "ShowEpisode");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BackgroundImageId", table: "BumperTemplate");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "StillPath",
|
||||
table: "ShowEpisode",
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BackgroundImageExtension",
|
||||
table: "BumperTemplate",
|
||||
type: "character varying(16)",
|
||||
maxLength: 16,
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+131
-131
@@ -1,131 +1,131 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperTextVariants : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperTextVariant",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
BumperTemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
NowLabel = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
NextLabel = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
Line1 = table.Column<string>(
|
||||
type: "character varying(120)",
|
||||
maxLength: 120,
|
||||
nullable: false
|
||||
),
|
||||
Line2 = table.Column<string>(
|
||||
type: "character varying(120)",
|
||||
maxLength: 120,
|
||||
nullable: false
|
||||
),
|
||||
Trigger = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperTextVariant", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
column: x => x.BumperTemplateId,
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperTextVariant_BumperTemplateId_Position",
|
||||
table: "BumperTextVariant",
|
||||
columns: new[] { "BumperTemplateId", "Position" }
|
||||
);
|
||||
|
||||
// Каждому блоку — дефолтный подблок «Сейчас/Далее» с прежними подписями канала; правило
|
||||
// показа переносим из старой галочки (только на смене шоу → OnShowChange=0, иначе Both=2).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT t."Id" AS tid, c."BumperNowLabel" AS nl, c."BumperNextLabel" AS xl,
|
||||
c."BumperOnlyBetweenDifferentShows" AS only_diff
|
||||
FROM "BumperTemplate" t
|
||||
JOIN "Channels" c ON c."Id" = t."ChannelId"
|
||||
LOOP
|
||||
INSERT INTO "BumperTextVariant"
|
||||
("Id", "BumperTemplateId", "Position", "Name", "Kind",
|
||||
"NowLabel", "NextLabel", "Line1", "Line2", "Trigger", "CreatedAt")
|
||||
VALUES (gen_random_uuid(), r.tid, 0, 'Текст 1', 0,
|
||||
COALESCE(NULLIF(r.nl, ''), 'СЕЙЧАС'), COALESCE(NULLIF(r.xl, ''), 'ДАЛЕЕ'),
|
||||
'', '', CASE WHEN r.only_diff THEN 0 ELSE 2 END, now());
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNextLabel", table: "Channels");
|
||||
migrationBuilder.DropColumn(name: "BumperNowLabel", table: "Channels");
|
||||
migrationBuilder.DropColumn(name: "BumperOnlyBetweenDifferentShows", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperTextVariant");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNextLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNowLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumperOnlyBetweenDifferentShows",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperTextVariants : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BumperTextVariant",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
BumperTemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
NowLabel = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
NextLabel = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
Line1 = table.Column<string>(
|
||||
type: "character varying(120)",
|
||||
maxLength: 120,
|
||||
nullable: false
|
||||
),
|
||||
Line2 = table.Column<string>(
|
||||
type: "character varying(120)",
|
||||
maxLength: 120,
|
||||
nullable: false
|
||||
),
|
||||
Trigger = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BumperTextVariant", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
column: x => x.BumperTemplateId,
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BumperTextVariant_BumperTemplateId_Position",
|
||||
table: "BumperTextVariant",
|
||||
columns: new[] { "BumperTemplateId", "Position" }
|
||||
);
|
||||
|
||||
// Каждому блоку — дефолтный подблок «Сейчас/Далее» с прежними подписями канала; правило
|
||||
// показа переносим из старой галочки (только на смене шоу → OnShowChange=0, иначе Both=2).
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DO $$
|
||||
DECLARE r RECORD;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT t."Id" AS tid, c."BumperNowLabel" AS nl, c."BumperNextLabel" AS xl,
|
||||
c."BumperOnlyBetweenDifferentShows" AS only_diff
|
||||
FROM "BumperTemplate" t
|
||||
JOIN "Channels" c ON c."Id" = t."ChannelId"
|
||||
LOOP
|
||||
INSERT INTO "BumperTextVariant"
|
||||
("Id", "BumperTemplateId", "Position", "Name", "Kind",
|
||||
"NowLabel", "NextLabel", "Line1", "Line2", "Trigger", "CreatedAt")
|
||||
VALUES (gen_random_uuid(), r.tid, 0, 'Текст 1', 0,
|
||||
COALESCE(NULLIF(r.nl, ''), 'СЕЙЧАС'), COALESCE(NULLIF(r.xl, ''), 'ДАЛЕЕ'),
|
||||
'', '', CASE WHEN r.only_diff THEN 0 ELSE 2 END, now());
|
||||
END LOOP;
|
||||
END $$;
|
||||
"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperNextLabel", table: "Channels");
|
||||
migrationBuilder.DropColumn(name: "BumperNowLabel", table: "Channels");
|
||||
migrationBuilder.DropColumn(name: "BumperOnlyBetweenDifferentShows", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "BumperTextVariant");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNextLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BumperNowLabel",
|
||||
table: "Channels",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: ""
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "BumperOnlyBetweenDifferentShows",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+125
-125
@@ -1,125 +1,125 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperChancesWeightsAndScheduleVariant : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariant"
|
||||
);
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_BumperTextVariant",
|
||||
table: "BumperTextVariant"
|
||||
);
|
||||
|
||||
migrationBuilder.RenameTable(name: "BumperTextVariant", newName: "BumperTextVariants");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_BumperTextVariant_BumperTemplateId_Position",
|
||||
table: "BumperTextVariants",
|
||||
newName: "IX_BumperTextVariants_BumperTemplateId_Position"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BumperVariantId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Существующим каналам — 1.0 (заставка на каждом подходящем переходе, как было до фичи).
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperEpisodeChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 1.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperShowChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 1.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Weight",
|
||||
table: "BumperTextVariants",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 1
|
||||
);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_BumperTextVariants",
|
||||
table: "BumperTextVariants",
|
||||
column: "Id"
|
||||
);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariants",
|
||||
column: "BumperTemplateId",
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariants"
|
||||
);
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_BumperTextVariants",
|
||||
table: "BumperTextVariants"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperVariantId", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperEpisodeChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperShowChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Weight", table: "BumperTextVariants");
|
||||
|
||||
migrationBuilder.RenameTable(name: "BumperTextVariants", newName: "BumperTextVariant");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_BumperTextVariants_BumperTemplateId_Position",
|
||||
table: "BumperTextVariant",
|
||||
newName: "IX_BumperTextVariant_BumperTemplateId_Position"
|
||||
);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_BumperTextVariant",
|
||||
table: "BumperTextVariant",
|
||||
column: "Id"
|
||||
);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariant",
|
||||
column: "BumperTemplateId",
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperChancesWeightsAndScheduleVariant : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariant"
|
||||
);
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_BumperTextVariant",
|
||||
table: "BumperTextVariant"
|
||||
);
|
||||
|
||||
migrationBuilder.RenameTable(name: "BumperTextVariant", newName: "BumperTextVariants");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_BumperTextVariant_BumperTemplateId_Position",
|
||||
table: "BumperTextVariants",
|
||||
newName: "IX_BumperTextVariants_BumperTemplateId_Position"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "BumperVariantId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
// Существующим каналам — 1.0 (заставка на каждом подходящем переходе, как было до фичи).
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperEpisodeChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 1.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperShowChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 1.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Weight",
|
||||
table: "BumperTextVariants",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 1
|
||||
);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_BumperTextVariants",
|
||||
table: "BumperTextVariants",
|
||||
column: "Id"
|
||||
);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariants",
|
||||
column: "BumperTemplateId",
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariants"
|
||||
);
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_BumperTextVariants",
|
||||
table: "BumperTextVariants"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperVariantId", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperEpisodeChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperShowChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Weight", table: "BumperTextVariants");
|
||||
|
||||
migrationBuilder.RenameTable(name: "BumperTextVariants", newName: "BumperTextVariant");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_BumperTextVariants_BumperTemplateId_Position",
|
||||
table: "BumperTextVariant",
|
||||
newName: "IX_BumperTextVariant_BumperTemplateId_Position"
|
||||
);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_BumperTextVariant",
|
||||
table: "BumperTextVariant",
|
||||
column: "Id"
|
||||
);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_BumperTextVariant_BumperTemplate_BumperTemplateId",
|
||||
table: "BumperTextVariant",
|
||||
column: "BumperTemplateId",
|
||||
principalTable: "BumperTemplate",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+59
-59
@@ -1,59 +1,59 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelShowPreferredHours : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "PreferredWeightMultiplier",
|
||||
table: "ChannelShow",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 3
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShowHour",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
StartHour = table.Column<int>(type: "integer", nullable: false),
|
||||
EndHour = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShowHour", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShowHour_ChannelShow_ChannelShowId",
|
||||
column: x => x.ChannelShowId,
|
||||
principalTable: "ChannelShow",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShowHour_ChannelShowId",
|
||||
table: "ChannelShowHour",
|
||||
column: "ChannelShowId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelShowHour");
|
||||
|
||||
migrationBuilder.DropColumn(name: "PreferredWeightMultiplier", table: "ChannelShow");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelShowPreferredHours : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "PreferredWeightMultiplier",
|
||||
table: "ChannelShow",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 3
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShowHour",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
StartHour = table.Column<int>(type: "integer", nullable: false),
|
||||
EndHour = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShowHour", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShowHour_ChannelShow_ChannelShowId",
|
||||
column: x => x.ChannelShowId,
|
||||
principalTable: "ChannelShow",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShowHour_ChannelShowId",
|
||||
table: "ChannelShowHour",
|
||||
column: "ChannelShowId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelShowHour");
|
||||
|
||||
migrationBuilder.DropColumn(name: "PreferredWeightMultiplier", table: "ChannelShow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+102
-102
@@ -1,102 +1,102 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class WeeklyProgrammingOverrides : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "StartsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone"
|
||||
);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "DayOfWeek",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "EndMinute",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Recurrence",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "StartMinute",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "DayOfWeek", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "EndMinute", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Recurrence", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "StartMinute", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "StartsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTimeOffset(
|
||||
new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
new TimeSpan(0, 0, 0, 0, 0)
|
||||
),
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTimeOffset(
|
||||
new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
new TimeSpan(0, 0, 0, 0, 0)
|
||||
),
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class WeeklyProgrammingOverrides : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "StartsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone"
|
||||
);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "DayOfWeek",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "EndMinute",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Recurrence",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "StartMinute",
|
||||
table: "ProgrammingOverride",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "DayOfWeek", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "EndMinute", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Recurrence", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "StartMinute", table: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "StartsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTimeOffset(
|
||||
new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
new TimeSpan(0, 0, 0, 0, 0)
|
||||
),
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTimeOffset(
|
||||
new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
new TimeSpan(0, 0, 0, 0, 0)
|
||||
),
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
-49
@@ -1,49 +1,49 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperAssetRenderContext : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ChannelId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TemplateId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "VariantId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "ChannelId", table: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TemplateId", table: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "VariantId", table: "BumperAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BumperAssetRenderContext : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ChannelId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TemplateId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "VariantId",
|
||||
table: "BumperAssets",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "ChannelId", table: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TemplateId", table: "BumperAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "VariantId", table: "BumperAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+37
-37
@@ -1,37 +1,37 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MediaProcessingTiming : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeSpan>(
|
||||
name: "ProcessingDuration",
|
||||
table: "MediaAssets",
|
||||
type: "interval",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<DateTimeOffset>(
|
||||
name: "ProcessingStartedAt",
|
||||
table: "MediaAssets",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "ProcessingDuration", table: "MediaAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "ProcessingStartedAt", table: "MediaAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MediaProcessingTiming : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeSpan>(
|
||||
name: "ProcessingDuration",
|
||||
table: "MediaAssets",
|
||||
type: "interval",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<DateTimeOffset>(
|
||||
name: "ProcessingStartedAt",
|
||||
table: "MediaAssets",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "ProcessingDuration", table: "MediaAssets");
|
||||
|
||||
migrationBuilder.DropColumn(name: "ProcessingStartedAt", table: "MediaAssets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowAudience : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "Audience", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowAudience : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "Audience", table: "Shows");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,132 +1,132 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGenres : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Genres",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Slug = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Genres", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GenreAliases",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GenreId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Value = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GenreAliases", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GenreAliases_Genres_GenreId",
|
||||
column: x => x.GenreId,
|
||||
principalTable: "Genres",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShowGenres",
|
||||
columns: table => new
|
||||
{
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GenreId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsPrimary = table.Column<bool>(type: "boolean", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShowGenres", x => new { x.ShowId, x.GenreId });
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowGenres_Genres_GenreId",
|
||||
column: x => x.GenreId,
|
||||
principalTable: "Genres",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowGenres_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GenreAliases_GenreId",
|
||||
table: "GenreAliases",
|
||||
column: "GenreId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GenreAliases_Value",
|
||||
table: "GenreAliases",
|
||||
column: "Value",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Genres_Slug",
|
||||
table: "Genres",
|
||||
column: "Slug",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowGenres_GenreId",
|
||||
table: "ShowGenres",
|
||||
column: "GenreId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "GenreAliases");
|
||||
|
||||
migrationBuilder.DropTable(name: "ShowGenres");
|
||||
|
||||
migrationBuilder.DropTable(name: "Genres");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGenres : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Genres",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Slug = table.Column<string>(
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: false
|
||||
),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Genres", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GenreAliases",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GenreId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Value = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GenreAliases", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GenreAliases_Genres_GenreId",
|
||||
column: x => x.GenreId,
|
||||
principalTable: "Genres",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShowGenres",
|
||||
columns: table => new
|
||||
{
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GenreId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsPrimary = table.Column<bool>(type: "boolean", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShowGenres", x => new { x.ShowId, x.GenreId });
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowGenres_Genres_GenreId",
|
||||
column: x => x.GenreId,
|
||||
principalTable: "Genres",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShowGenres_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GenreAliases_GenreId",
|
||||
table: "GenreAliases",
|
||||
column: "GenreId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GenreAliases_Value",
|
||||
table: "GenreAliases",
|
||||
column: "Value",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Genres_Slug",
|
||||
table: "Genres",
|
||||
column: "Slug",
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowGenres_GenreId",
|
||||
table: "ShowGenres",
|
||||
column: "GenreId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "GenreAliases");
|
||||
|
||||
migrationBuilder.DropTable(name: "ShowGenres");
|
||||
|
||||
migrationBuilder.DropTable(name: "Genres");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +1,98 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddCollections : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Collections",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
PosterImageId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Collections", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CollectionItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CollectionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CollectionItems", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectionItems_Collections_CollectionId",
|
||||
column: x => x.CollectionId,
|
||||
principalTable: "Collections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectionItems_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_CollectionId_Position",
|
||||
table: "CollectionItems",
|
||||
columns: new[] { "CollectionId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_CollectionId_ShowId",
|
||||
table: "CollectionItems",
|
||||
columns: new[] { "CollectionId", "ShowId" },
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_ShowId",
|
||||
table: "CollectionItems",
|
||||
column: "ShowId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "CollectionItems");
|
||||
|
||||
migrationBuilder.DropTable(name: "Collections");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddCollections : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Collections",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
PosterImageId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Collections", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CollectionItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CollectionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CollectionItems", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectionItems_Collections_CollectionId",
|
||||
column: x => x.CollectionId,
|
||||
principalTable: "Collections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectionItems_Shows_ShowId",
|
||||
column: x => x.ShowId,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_CollectionId_Position",
|
||||
table: "CollectionItems",
|
||||
columns: new[] { "CollectionId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_CollectionId_ShowId",
|
||||
table: "CollectionItems",
|
||||
columns: new[] { "CollectionId", "ShowId" },
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectionItems_ShowId",
|
||||
table: "CollectionItems",
|
||||
column: "ShowId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "CollectionItems");
|
||||
|
||||
migrationBuilder.DropTable(name: "Collections");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGroups : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Groups",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
FilterJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
ItemCount = table.Column<int>(type: "integer", nullable: false),
|
||||
UnitCount = table.Column<int>(type: "integer", nullable: false),
|
||||
TotalDuration = table.Column<TimeSpan>(type: "interval", nullable: false),
|
||||
StatsComputedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Groups", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GroupItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ElementKind = table.Column<int>(type: "integer", nullable: false),
|
||||
ElementId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GroupItems", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupItems_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_ElementKind_ElementId",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "ElementKind", "ElementId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_GroupId_ElementKind_ElementId",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "GroupId", "ElementKind", "ElementId" },
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_GroupId_Position",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "GroupId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "GroupItems");
|
||||
|
||||
migrationBuilder.DropTable(name: "Groups");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGroups : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Groups",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Description = table.Column<string>(
|
||||
type: "character varying(2048)",
|
||||
maxLength: 2048,
|
||||
nullable: true
|
||||
),
|
||||
FilterJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
ItemCount = table.Column<int>(type: "integer", nullable: false),
|
||||
UnitCount = table.Column<int>(type: "integer", nullable: false),
|
||||
TotalDuration = table.Column<TimeSpan>(type: "interval", nullable: false),
|
||||
StatsComputedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Groups", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GroupItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ElementKind = table.Column<int>(type: "integer", nullable: false),
|
||||
ElementId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GroupItems", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GroupItems_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_ElementKind_ElementId",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "ElementKind", "ElementId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_GroupId_ElementKind_ElementId",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "GroupId", "ElementKind", "ElementId" },
|
||||
unique: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GroupItems_GroupId_Position",
|
||||
table: "GroupItems",
|
||||
columns: new[] { "GroupId", "Position" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "GroupItems");
|
||||
|
||||
migrationBuilder.DropTable(name: "Groups");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+224
-224
@@ -1,224 +1,224 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddScheduleTemplate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeOnly>(
|
||||
name: "DayStartTime",
|
||||
table: "Channels",
|
||||
type: "time without time zone",
|
||||
nullable: false,
|
||||
defaultValue: new TimeOnly(0, 0, 0)
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Number",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TemplateId",
|
||||
table: "Channels",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "UtcOffsetMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ScheduleTemplates",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
FallbackGroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Revision = table.Column<int>(type: "integer", nullable: false),
|
||||
AppliedRevision = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ScheduleTemplates", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GridLayers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Priority = table.Column<int>(type: "integer", nullable: false),
|
||||
ApplicabilityJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsBackground = table.Column<bool>(type: "boolean", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GridLayers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GridLayers_ScheduleTemplates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "ScheduleTemplates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Slots",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
LayerId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weekday = table.Column<int>(type: "integer", nullable: true),
|
||||
TargetStart = table.Column<TimeOnly>(
|
||||
type: "time without time zone",
|
||||
nullable: false
|
||||
),
|
||||
TargetDurationMinutes = table.Column<int>(type: "integer", nullable: false),
|
||||
Title = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Daypart = table.Column<int>(type: "integer", nullable: false),
|
||||
SlotKind = table.Column<int>(type: "integer", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
StrategyJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
RepeatSourceJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
OverflowPolicy = table.Column<int>(type: "integer", nullable: false),
|
||||
IsAnchor = table.Column<bool>(type: "boolean", nullable: false),
|
||||
MaxDriftMinutes = table.Column<int>(type: "integer", nullable: false),
|
||||
SnapToMinutes = table.Column<int>(type: "integer", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Slots", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Slots_GridLayers_LayerId",
|
||||
column: x => x.LayerId,
|
||||
principalTable: "GridLayers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_Slots_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SlotStates",
|
||||
columns: table => new
|
||||
{
|
||||
SlotId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CurrentElementKind = table.Column<int>(type: "integer", nullable: true),
|
||||
CurrentElementId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
NextUnitIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SlotStates", x => x.SlotId);
|
||||
table.ForeignKey(
|
||||
name: "FK_SlotStates_Slots_SlotId",
|
||||
column: x => x.SlotId,
|
||||
principalTable: "Slots",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_Number",
|
||||
table: "Channels",
|
||||
column: "Number",
|
||||
unique: true,
|
||||
filter: "\"Number\" IS NOT NULL"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GridLayers_TemplateId_Priority",
|
||||
table: "GridLayers",
|
||||
columns: new[] { "TemplateId", "Priority" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleTemplates_ChannelId",
|
||||
table: "ScheduleTemplates",
|
||||
column: "ChannelId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Slots_GroupId",
|
||||
table: "Slots",
|
||||
column: "GroupId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Slots_LayerId_TargetStart",
|
||||
table: "Slots",
|
||||
columns: new[] { "LayerId", "TargetStart" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "SlotStates");
|
||||
|
||||
migrationBuilder.DropTable(name: "Slots");
|
||||
|
||||
migrationBuilder.DropTable(name: "GridLayers");
|
||||
|
||||
migrationBuilder.DropTable(name: "ScheduleTemplates");
|
||||
|
||||
migrationBuilder.DropIndex(name: "IX_Channels_Number", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "DayStartTime", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Number", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TemplateId", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "UtcOffsetMinutes", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddScheduleTemplate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeOnly>(
|
||||
name: "DayStartTime",
|
||||
table: "Channels",
|
||||
type: "time without time zone",
|
||||
nullable: false,
|
||||
defaultValue: new TimeOnly(0, 0, 0)
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Number",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TemplateId",
|
||||
table: "Channels",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "UtcOffsetMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ScheduleTemplates",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
FallbackGroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Revision = table.Column<int>(type: "integer", nullable: false),
|
||||
AppliedRevision = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ScheduleTemplates", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GridLayers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
Priority = table.Column<int>(type: "integer", nullable: false),
|
||||
ApplicabilityJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsBackground = table.Column<bool>(type: "boolean", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GridLayers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GridLayers_ScheduleTemplates_TemplateId",
|
||||
column: x => x.TemplateId,
|
||||
principalTable: "ScheduleTemplates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Slots",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
LayerId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weekday = table.Column<int>(type: "integer", nullable: true),
|
||||
TargetStart = table.Column<TimeOnly>(
|
||||
type: "time without time zone",
|
||||
nullable: false
|
||||
),
|
||||
TargetDurationMinutes = table.Column<int>(type: "integer", nullable: false),
|
||||
Title = table.Column<string>(
|
||||
type: "character varying(256)",
|
||||
maxLength: 256,
|
||||
nullable: false
|
||||
),
|
||||
Daypart = table.Column<int>(type: "integer", nullable: false),
|
||||
SlotKind = table.Column<int>(type: "integer", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
StrategyJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
RepeatSourceJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
OverflowPolicy = table.Column<int>(type: "integer", nullable: false),
|
||||
IsAnchor = table.Column<bool>(type: "boolean", nullable: false),
|
||||
MaxDriftMinutes = table.Column<int>(type: "integer", nullable: false),
|
||||
SnapToMinutes = table.Column<int>(type: "integer", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Slots", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Slots_GridLayers_LayerId",
|
||||
column: x => x.LayerId,
|
||||
principalTable: "GridLayers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_Slots_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SlotStates",
|
||||
columns: table => new
|
||||
{
|
||||
SlotId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CurrentElementKind = table.Column<int>(type: "integer", nullable: true),
|
||||
CurrentElementId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
NextUnitIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SlotStates", x => x.SlotId);
|
||||
table.ForeignKey(
|
||||
name: "FK_SlotStates_Slots_SlotId",
|
||||
column: x => x.SlotId,
|
||||
principalTable: "Slots",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_Number",
|
||||
table: "Channels",
|
||||
column: "Number",
|
||||
unique: true,
|
||||
filter: "\"Number\" IS NOT NULL"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GridLayers_TemplateId_Priority",
|
||||
table: "GridLayers",
|
||||
columns: new[] { "TemplateId", "Priority" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleTemplates_ChannelId",
|
||||
table: "ScheduleTemplates",
|
||||
column: "ChannelId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Slots_GroupId",
|
||||
table: "Slots",
|
||||
column: "GroupId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Slots_LayerId_TargetStart",
|
||||
table: "Slots",
|
||||
columns: new[] { "LayerId", "TargetStart" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "SlotStates");
|
||||
|
||||
migrationBuilder.DropTable(name: "Slots");
|
||||
|
||||
migrationBuilder.DropTable(name: "GridLayers");
|
||||
|
||||
migrationBuilder.DropTable(name: "ScheduleTemplates");
|
||||
|
||||
migrationBuilder.DropIndex(name: "IX_Channels_Number", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "DayStartTime", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "Number", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TemplateId", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "UtcOffsetMinutes", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+59
-59
@@ -1,59 +1,59 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ScheduleEntryTrace : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "SlotId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TraceJson",
|
||||
table: "ScheduleEntries",
|
||||
type: "jsonb",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId_StartsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId", "StartsAtUtc" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId_StartsAtUtc",
|
||||
table: "ScheduleEntries"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "SlotId", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TraceJson", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ScheduleEntryTrace : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries"
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "SlotId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TraceJson",
|
||||
table: "ScheduleEntries",
|
||||
type: "jsonb",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId_StartsAtUtc",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId", "StartsAtUtc" }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId_StartsAtUtc",
|
||||
table: "ScheduleEntries"
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "SlotId", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.DropColumn(name: "TraceJson", table: "ScheduleEntries");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ScheduleEntries_ChannelId_ShowId",
|
||||
table: "ScheduleEntries",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+219
-219
@@ -1,219 +1,219 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DropLegacyRotation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelAd");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShowHour");
|
||||
|
||||
migrationBuilder.DropTable(name: "OverrideShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "AdInsertion", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "AdsPerBreak", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextAdIndex", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AdInsertion",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AdsPerBreak",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextAdIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelAd",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelAd", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelAd_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
NextEpisodeIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
PreferredWeightMultiplier = table.Column<int>(
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 3
|
||||
),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShow_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProgrammingOverride",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
DayOfWeek = table.Column<int>(type: "integer", nullable: true),
|
||||
EndMinute = table.Column<int>(type: "integer", nullable: true),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
Mode = table.Column<int>(type: "integer", nullable: false),
|
||||
Recurrence = table.Column<int>(type: "integer", nullable: false),
|
||||
StartMinute = table.Column<int>(type: "integer", nullable: true),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProgrammingOverride", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProgrammingOverride_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShowHour",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
EndHour = table.Column<int>(type: "integer", nullable: false),
|
||||
StartHour = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShowHour", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShowHour_ChannelShow_ChannelShowId",
|
||||
column: x => x.ChannelShowId,
|
||||
principalTable: "ChannelShow",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OverrideShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProgrammingOverrideId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OverrideShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OverrideShow_ProgrammingOverride_ProgrammingOverrideId",
|
||||
column: x => x.ProgrammingOverrideId,
|
||||
principalTable: "ProgrammingOverride",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelAd_ChannelId_Position",
|
||||
table: "ChannelAd",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShow_ChannelId_ShowId",
|
||||
table: "ChannelShow",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShowHour_ChannelShowId",
|
||||
table: "ChannelShowHour",
|
||||
column: "ChannelShowId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OverrideShow_ProgrammingOverrideId",
|
||||
table: "OverrideShow",
|
||||
column: "ProgrammingOverrideId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProgrammingOverride_ChannelId_StartsAtUtc_EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc", "EndsAtUtc" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DropLegacyRotation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "ChannelAd");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShowHour");
|
||||
|
||||
migrationBuilder.DropTable(name: "OverrideShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ChannelShow");
|
||||
|
||||
migrationBuilder.DropTable(name: "ProgrammingOverride");
|
||||
|
||||
migrationBuilder.DropColumn(name: "AdInsertion", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "AdsPerBreak", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextAdIndex", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AdInsertion",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AdsPerBreak",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextAdIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelAd",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MediaAssetId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelAd", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelAd_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
BlockMode = table.Column<int>(type: "integer", nullable: false),
|
||||
BlockValue = table.Column<int>(type: "integer", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
NextEpisodeIndex = table.Column<int>(type: "integer", nullable: false),
|
||||
PreferredWeightMultiplier = table.Column<int>(
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 3
|
||||
),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShow_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProgrammingOverride",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
DayOfWeek = table.Column<int>(type: "integer", nullable: true),
|
||||
EndMinute = table.Column<int>(type: "integer", nullable: true),
|
||||
EndsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
Mode = table.Column<int>(type: "integer", nullable: false),
|
||||
Recurrence = table.Column<int>(type: "integer", nullable: false),
|
||||
StartMinute = table.Column<int>(type: "integer", nullable: true),
|
||||
StartsAtUtc = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: true
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProgrammingOverride", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProgrammingOverride_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelShowHour",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
EndHour = table.Column<int>(type: "integer", nullable: false),
|
||||
StartHour = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelShowHour", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelShowHour_ChannelShow_ChannelShowId",
|
||||
column: x => x.ChannelShowId,
|
||||
principalTable: "ChannelShow",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OverrideShow",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProgrammingOverrideId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ShowId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Weight = table.Column<int>(type: "integer", nullable: false),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OverrideShow", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OverrideShow_ProgrammingOverride_ProgrammingOverrideId",
|
||||
column: x => x.ProgrammingOverrideId,
|
||||
principalTable: "ProgrammingOverride",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelAd_ChannelId_Position",
|
||||
table: "ChannelAd",
|
||||
columns: new[] { "ChannelId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShow_ChannelId_ShowId",
|
||||
table: "ChannelShow",
|
||||
columns: new[] { "ChannelId", "ShowId" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelShowHour_ChannelShowId",
|
||||
table: "ChannelShowHour",
|
||||
column: "ChannelShowId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OverrideShow_ProgrammingOverrideId",
|
||||
table: "OverrideShow",
|
||||
column: "ProgrammingOverrideId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProgrammingOverride_ChannelId_StartsAtUtc_EndsAtUtc",
|
||||
table: "ProgrammingOverride",
|
||||
columns: new[] { "ChannelId", "StartsAtUtc", "EndsAtUtc" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+125
-125
@@ -1,125 +1,125 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddJunctionTemplates : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "JunctionAfterId",
|
||||
table: "Slots",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "JunctionBetweenId",
|
||||
table: "Slots",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "DefaultJunctionId",
|
||||
table: "ScheduleTemplates",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "JunctionTemplates",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_JunctionTemplates", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "JunctionElements",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
JunctionTemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
BumperTemplateId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
AmountMode = table.Column<int>(type: "integer", nullable: false),
|
||||
AmountValue = table.Column<int>(type: "integer", nullable: false),
|
||||
IsRequired = table.Column<bool>(type: "boolean", nullable: false),
|
||||
ConditionsJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_JunctionElements", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_JunctionElements_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_JunctionElements_JunctionTemplates_JunctionTemplateId",
|
||||
column: x => x.JunctionTemplateId,
|
||||
principalTable: "JunctionTemplates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionElements_GroupId",
|
||||
table: "JunctionElements",
|
||||
column: "GroupId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionElements_JunctionTemplateId_Position",
|
||||
table: "JunctionElements",
|
||||
columns: new[] { "JunctionTemplateId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionTemplates_ChannelId",
|
||||
table: "JunctionTemplates",
|
||||
column: "ChannelId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "JunctionElements");
|
||||
|
||||
migrationBuilder.DropTable(name: "JunctionTemplates");
|
||||
|
||||
migrationBuilder.DropColumn(name: "JunctionAfterId", table: "Slots");
|
||||
|
||||
migrationBuilder.DropColumn(name: "JunctionBetweenId", table: "Slots");
|
||||
|
||||
migrationBuilder.DropColumn(name: "DefaultJunctionId", table: "ScheduleTemplates");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddJunctionTemplates : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "JunctionAfterId",
|
||||
table: "Slots",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "JunctionBetweenId",
|
||||
table: "Slots",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "DefaultJunctionId",
|
||||
table: "ScheduleTemplates",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "JunctionTemplates",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ChannelId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(
|
||||
type: "character varying(128)",
|
||||
maxLength: 128,
|
||||
nullable: false
|
||||
),
|
||||
CreatedAt = table.Column<DateTimeOffset>(
|
||||
type: "timestamp with time zone",
|
||||
nullable: false
|
||||
),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_JunctionTemplates", x => x.Id);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "JunctionElements",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
JunctionTemplateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Position = table.Column<int>(type: "integer", nullable: false),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
GroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
BumperTemplateId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
AmountMode = table.Column<int>(type: "integer", nullable: false),
|
||||
AmountValue = table.Column<int>(type: "integer", nullable: false),
|
||||
IsRequired = table.Column<bool>(type: "boolean", nullable: false),
|
||||
ConditionsJson = table.Column<string>(type: "jsonb", nullable: true),
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_JunctionElements", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_JunctionElements_Groups_GroupId",
|
||||
column: x => x.GroupId,
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict
|
||||
);
|
||||
table.ForeignKey(
|
||||
name: "FK_JunctionElements_JunctionTemplates_JunctionTemplateId",
|
||||
column: x => x.JunctionTemplateId,
|
||||
principalTable: "JunctionTemplates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionElements_GroupId",
|
||||
table: "JunctionElements",
|
||||
column: "GroupId"
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionElements_JunctionTemplateId_Position",
|
||||
table: "JunctionElements",
|
||||
columns: new[] { "JunctionTemplateId", "Position" }
|
||||
);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_JunctionTemplates_ChannelId",
|
||||
table: "JunctionTemplates",
|
||||
column: "ChannelId"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "JunctionElements");
|
||||
|
||||
migrationBuilder.DropTable(name: "JunctionTemplates");
|
||||
|
||||
migrationBuilder.DropColumn(name: "JunctionAfterId", table: "Slots");
|
||||
|
||||
migrationBuilder.DropColumn(name: "JunctionBetweenId", table: "Slots");
|
||||
|
||||
migrationBuilder.DropColumn(name: "DefaultJunctionId", table: "ScheduleTemplates");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+64
-64
@@ -1,64 +1,64 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DropDeadBumperSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Значение 0 (прежняя «ротация») из перечисления убрано: курсора ротации больше нет,
|
||||
// и выбор молча вырождался в случайный. Переводим такие каналы на выбор по весам.
|
||||
migrationBuilder.Sql(
|
||||
"""UPDATE "Channels" SET "BumperSelection" = 3 WHERE "BumperSelection" = 0;"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperEpisodeChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMinIntervalMinutes", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperShowChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextBumperIndex", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperEpisodeChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMinIntervalMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperShowChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextBumperIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DropDeadBumperSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Значение 0 (прежняя «ротация») из перечисления убрано: курсора ротации больше нет,
|
||||
// и выбор молча вырождался в случайный. Переводим такие каналы на выбор по весам.
|
||||
migrationBuilder.Sql(
|
||||
"""UPDATE "Channels" SET "BumperSelection" = 3 WHERE "BumperSelection" = 0;"""
|
||||
);
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperEpisodeChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperMinIntervalMinutes", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "BumperShowChangeChance", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "NextBumperIndex", table: "Channels");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperEpisodeChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BumperMinIntervalMinutes",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BumperShowChangeChance",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "NextBumperIndex",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -1,27 +1,27 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class TemplatePlanningRules : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "RulesJson",
|
||||
table: "ScheduleTemplates",
|
||||
type: "jsonb",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "RulesJson", table: "ScheduleTemplates");
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class TemplatePlanningRules : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "RulesJson",
|
||||
table: "ScheduleTemplates",
|
||||
type: "jsonb",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "RulesJson", table: "ScheduleTemplates");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+68
-68
@@ -1,68 +1,68 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelViewerSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "AnalogFilterStrength",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "LogoCorner",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "LogoImageId",
|
||||
table: "Channels",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "LogoOpacity",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "ShowClock",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "AnalogFilterStrength", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoCorner", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoImageId", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoOpacity", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "ShowClock", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChannelViewerSettings : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "AnalogFilterStrength",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "LogoCorner",
|
||||
table: "Channels",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "LogoImageId",
|
||||
table: "Channels",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "LogoOpacity",
|
||||
table: "Channels",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0
|
||||
);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "ShowClock",
|
||||
table: "Channels",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "AnalogFilterStrength", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoCorner", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoImageId", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "LogoOpacity", table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(name: "ShowClock", table: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,28 +1,28 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ScheduleEntryCollection : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "CollectionId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "CollectionId", table: "ScheduleEntries");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ScheduleEntryCollection : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "CollectionId",
|
||||
table: "ScheduleEntries",
|
||||
type: "uuid",
|
||||
nullable: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(name: "CollectionId", table: "ScheduleEntries");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowAudienceMpaa : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer",
|
||||
oldNullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TeleWave.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ShowAudienceMpaa : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer"
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Audience",
|
||||
table: "Shows",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer",
|
||||
oldNullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Domain.Auth;
|
||||
using TeleWave.Domain.Broadcast;
|
||||
using TeleWave.Domain.Images;
|
||||
using TeleWave.Domain.Library;
|
||||
using TeleWave.Domain.Media;
|
||||
using TeleWave.Domain.Programming;
|
||||
using TeleWave.Domain.Settings;
|
||||
using TeleWave.Infrastructure.Identity;
|
||||
|
||||
namespace TeleWave.Infrastructure.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Корневой DbContext приложения: Identity-схема (пользователи/роли) + сущности домена
|
||||
/// (добавляются по мере реализации фич).
|
||||
/// </summary>
|
||||
public class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
: IdentityDbContext<AppUser, AppRole, Guid>(options),
|
||||
IAppDbContext
|
||||
{
|
||||
public DbSet<RefreshToken> RefreshTokens => Set<RefreshToken>();
|
||||
public DbSet<MediaAsset> MediaAssets => Set<MediaAsset>();
|
||||
public DbSet<Show> Shows => Set<Show>();
|
||||
public DbSet<Genre> Genres => Set<Genre>();
|
||||
public DbSet<GenreAlias> GenreAliases => Set<GenreAlias>();
|
||||
public DbSet<ShowGenre> ShowGenres => Set<ShowGenre>();
|
||||
public DbSet<Collection> Collections => Set<Collection>();
|
||||
public DbSet<CollectionItem> CollectionItems => Set<CollectionItem>();
|
||||
public DbSet<Group> Groups => Set<Group>();
|
||||
public DbSet<GroupItem> GroupItems => Set<GroupItem>();
|
||||
public DbSet<ScheduleTemplate> ScheduleTemplates => Set<ScheduleTemplate>();
|
||||
public DbSet<GridLayer> GridLayers => Set<GridLayer>();
|
||||
public DbSet<Slot> Slots => Set<Slot>();
|
||||
public DbSet<SlotState> SlotStates => Set<SlotState>();
|
||||
public DbSet<JunctionTemplate> JunctionTemplates => Set<JunctionTemplate>();
|
||||
public DbSet<JunctionElement> JunctionElements => Set<JunctionElement>();
|
||||
public DbSet<Channel> Channels => Set<Channel>();
|
||||
public DbSet<ScheduleEntry> ScheduleEntries => Set<ScheduleEntry>();
|
||||
public DbSet<BumperTextVariant> BumperTextVariants => Set<BumperTextVariant>();
|
||||
public DbSet<BumperAsset> BumperAssets => Set<BumperAsset>();
|
||||
public DbSet<AppSetting> AppSettings => Set<AppSetting>();
|
||||
public DbSet<Image> Images => Set<Image>();
|
||||
|
||||
public Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken) =>
|
||||
Database.BeginTransactionAsync(cancellationToken);
|
||||
|
||||
public Task AcquireChannelLockAsync(Guid channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
// pg_advisory_xact_lock(bigint) освобождается автоматически при завершении транзакции.
|
||||
// Ключ — стабильный int64 из GUID канала; коллизии между каналами лишь сериализуют их генерацию,
|
||||
// корректности не нарушают.
|
||||
var key = BitConverter.ToInt64(channelId.ToByteArray());
|
||||
return Database.ExecuteSqlAsync($"SELECT pg_advisory_xact_lock({key})", cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
builder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
|
||||
|
||||
// Guid-ключи доменных сущностей мы задаём сами в фабриках. Без этого EF считает выставленный
|
||||
// ключ признаком уже существующей строки и при добавлении дочерней сущности через коллекцию
|
||||
// отслеживаемого родителя (напр. show.AddEpisode) делает UPDATE вместо INSERT → «affected 0».
|
||||
foreach (var entityType in builder.Model.GetEntityTypes())
|
||||
{
|
||||
if (
|
||||
entityType.ClrType.Namespace?.StartsWith(
|
||||
"TeleWave.Domain",
|
||||
StringComparison.Ordinal
|
||||
) != true
|
||||
)
|
||||
continue;
|
||||
|
||||
var idProperty = entityType.FindProperty("Id");
|
||||
if (idProperty is not null && idProperty.ClrType == typeof(Guid))
|
||||
idProperty.ValueGenerated = ValueGenerated.Never;
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Domain.Auth;
|
||||
using TeleWave.Domain.Broadcast;
|
||||
using TeleWave.Domain.Images;
|
||||
using TeleWave.Domain.Library;
|
||||
using TeleWave.Domain.Media;
|
||||
using TeleWave.Domain.Programming;
|
||||
using TeleWave.Domain.Settings;
|
||||
using TeleWave.Infrastructure.Identity;
|
||||
|
||||
namespace TeleWave.Infrastructure.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Корневой DbContext приложения: Identity-схема (пользователи/роли) + сущности домена
|
||||
/// (добавляются по мере реализации фич).
|
||||
/// </summary>
|
||||
public class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
: IdentityDbContext<AppUser, AppRole, Guid>(options),
|
||||
IAppDbContext
|
||||
{
|
||||
public DbSet<RefreshToken> RefreshTokens => Set<RefreshToken>();
|
||||
public DbSet<MediaAsset> MediaAssets => Set<MediaAsset>();
|
||||
public DbSet<Show> Shows => Set<Show>();
|
||||
public DbSet<Genre> Genres => Set<Genre>();
|
||||
public DbSet<GenreAlias> GenreAliases => Set<GenreAlias>();
|
||||
public DbSet<ShowGenre> ShowGenres => Set<ShowGenre>();
|
||||
public DbSet<Collection> Collections => Set<Collection>();
|
||||
public DbSet<CollectionItem> CollectionItems => Set<CollectionItem>();
|
||||
public DbSet<Group> Groups => Set<Group>();
|
||||
public DbSet<GroupItem> GroupItems => Set<GroupItem>();
|
||||
public DbSet<ScheduleTemplate> ScheduleTemplates => Set<ScheduleTemplate>();
|
||||
public DbSet<GridLayer> GridLayers => Set<GridLayer>();
|
||||
public DbSet<Slot> Slots => Set<Slot>();
|
||||
public DbSet<SlotState> SlotStates => Set<SlotState>();
|
||||
public DbSet<JunctionTemplate> JunctionTemplates => Set<JunctionTemplate>();
|
||||
public DbSet<JunctionElement> JunctionElements => Set<JunctionElement>();
|
||||
public DbSet<Channel> Channels => Set<Channel>();
|
||||
public DbSet<ScheduleEntry> ScheduleEntries => Set<ScheduleEntry>();
|
||||
public DbSet<BumperTextVariant> BumperTextVariants => Set<BumperTextVariant>();
|
||||
public DbSet<BumperAsset> BumperAssets => Set<BumperAsset>();
|
||||
public DbSet<AppSetting> AppSettings => Set<AppSetting>();
|
||||
public DbSet<Image> Images => Set<Image>();
|
||||
|
||||
public Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken) =>
|
||||
Database.BeginTransactionAsync(cancellationToken);
|
||||
|
||||
public Task AcquireChannelLockAsync(Guid channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
// pg_advisory_xact_lock(bigint) освобождается автоматически при завершении транзакции.
|
||||
// Ключ — стабильный int64 из GUID канала; коллизии между каналами лишь сериализуют их генерацию,
|
||||
// корректности не нарушают.
|
||||
var key = BitConverter.ToInt64(channelId.ToByteArray());
|
||||
return Database.ExecuteSqlAsync($"SELECT pg_advisory_xact_lock({key})", cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
builder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
|
||||
|
||||
// Guid-ключи доменных сущностей мы задаём сами в фабриках. Без этого EF считает выставленный
|
||||
// ключ признаком уже существующей строки и при добавлении дочерней сущности через коллекцию
|
||||
// отслеживаемого родителя (напр. show.AddEpisode) делает UPDATE вместо INSERT → «affected 0».
|
||||
foreach (var entityType in builder.Model.GetEntityTypes())
|
||||
{
|
||||
if (
|
||||
entityType.ClrType.Namespace?.StartsWith(
|
||||
"TeleWave.Domain",
|
||||
StringComparison.Ordinal
|
||||
) != true
|
||||
)
|
||||
continue;
|
||||
|
||||
var idProperty = entityType.FindProperty("Id");
|
||||
if (idProperty is not null && idProperty.ClrType == typeof(Guid))
|
||||
idProperty.ValueGenerated = ValueGenerated.Never;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+61
-61
@@ -1,61 +1,61 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using TeleWave.Domain.Broadcast;
|
||||
|
||||
namespace TeleWave.Infrastructure.Persistence.Configurations;
|
||||
|
||||
public class ChannelConfiguration : IEntityTypeConfiguration<Channel>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Channel> builder)
|
||||
{
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
||||
builder.Property(x => x.Slug).IsRequired().HasMaxLength(128);
|
||||
builder.HasIndex(x => x.Slug).IsUnique();
|
||||
|
||||
// Номер канала уникален среди заданных: переключение вверх-вниз по номерам иначе неоднозначно.
|
||||
builder.HasIndex(x => x.Number).IsUnique().HasFilter("\"Number\" IS NOT NULL");
|
||||
|
||||
builder
|
||||
.HasMany(x => x.BumperTemplates)
|
||||
.WithOne()
|
||||
.HasForeignKey(t => t.ChannelId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Navigation(x => x.BumperTemplates).UsePropertyAccessMode(PropertyAccessMode.Field);
|
||||
}
|
||||
}
|
||||
|
||||
public class BumperTemplateConfiguration : IEntityTypeConfiguration<BumperTemplate>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<BumperTemplate> builder)
|
||||
{
|
||||
builder.HasIndex(x => new { x.ChannelId, x.Position });
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.BackgroundColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.BackgroundColor2).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.AccentColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.TextColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.AudioExtension).HasMaxLength(16);
|
||||
|
||||
builder
|
||||
.HasMany(x => x.Variants)
|
||||
.WithOne()
|
||||
.HasForeignKey(v => v.BumperTemplateId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Navigation(x => x.Variants).UsePropertyAccessMode(PropertyAccessMode.Field);
|
||||
}
|
||||
}
|
||||
|
||||
public class BumperTextVariantConfiguration : IEntityTypeConfiguration<BumperTextVariant>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<BumperTextVariant> builder)
|
||||
{
|
||||
builder.HasIndex(x => new { x.BumperTemplateId, x.Position });
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.NowLabel).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.NextLabel).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.Line1).IsRequired().HasMaxLength(120);
|
||||
builder.Property(x => x.Line2).IsRequired().HasMaxLength(120);
|
||||
builder.Property(x => x.Weight).HasDefaultValue(BumperTextVariant.DefaultWeight);
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using TeleWave.Domain.Broadcast;
|
||||
|
||||
namespace TeleWave.Infrastructure.Persistence.Configurations;
|
||||
|
||||
public class ChannelConfiguration : IEntityTypeConfiguration<Channel>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Channel> builder)
|
||||
{
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
||||
builder.Property(x => x.Slug).IsRequired().HasMaxLength(128);
|
||||
builder.HasIndex(x => x.Slug).IsUnique();
|
||||
|
||||
// Номер канала уникален среди заданных: переключение вверх-вниз по номерам иначе неоднозначно.
|
||||
builder.HasIndex(x => x.Number).IsUnique().HasFilter("\"Number\" IS NOT NULL");
|
||||
|
||||
builder
|
||||
.HasMany(x => x.BumperTemplates)
|
||||
.WithOne()
|
||||
.HasForeignKey(t => t.ChannelId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Navigation(x => x.BumperTemplates).UsePropertyAccessMode(PropertyAccessMode.Field);
|
||||
}
|
||||
}
|
||||
|
||||
public class BumperTemplateConfiguration : IEntityTypeConfiguration<BumperTemplate>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<BumperTemplate> builder)
|
||||
{
|
||||
builder.HasIndex(x => new { x.ChannelId, x.Position });
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.BackgroundColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.BackgroundColor2).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.AccentColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.TextColor).IsRequired().HasMaxLength(32);
|
||||
builder.Property(x => x.AudioExtension).HasMaxLength(16);
|
||||
|
||||
builder
|
||||
.HasMany(x => x.Variants)
|
||||
.WithOne()
|
||||
.HasForeignKey(v => v.BumperTemplateId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Navigation(x => x.Variants).UsePropertyAccessMode(PropertyAccessMode.Field);
|
||||
}
|
||||
}
|
||||
|
||||
public class BumperTextVariantConfiguration : IEntityTypeConfiguration<BumperTextVariant>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<BumperTextVariant> builder)
|
||||
{
|
||||
builder.HasIndex(x => new { x.BumperTemplateId, x.Position });
|
||||
builder.Property(x => x.Name).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.NowLabel).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.NextLabel).IsRequired().HasMaxLength(64);
|
||||
builder.Property(x => x.Line1).IsRequired().HasMaxLength(120);
|
||||
builder.Property(x => x.Line2).IsRequired().HasMaxLength(120);
|
||||
builder.Property(x => x.Weight).HasDefaultValue(BumperTextVariant.DefaultWeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Settings;
|
||||
using TeleWave.Domain.Settings;
|
||||
|
||||
namespace TeleWave.Infrastructure.Settings;
|
||||
|
||||
/// <summary>Настройки сайта поверх key-value таблицы AppSetting. Запись не сохраняет сама —
|
||||
/// сохранение выполняет UnitOfWorkBehavior команды (используется общий scoped-контекст).</summary>
|
||||
public sealed class SiteSettings(IAppDbContext dbContext) : ISiteSettings
|
||||
{
|
||||
public Task<bool> IsRegistrationEnabledAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetBoolSettingAsync(SettingKeys.RegistrationEnabled, false, cancellationToken);
|
||||
|
||||
public async Task SetRegistrationEnabledAsync(bool enabled, CancellationToken cancellationToken)
|
||||
{
|
||||
await UpsertAsync(
|
||||
SettingKeys.RegistrationEnabled,
|
||||
enabled ? "true" : "false",
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
public Task<string> GetPreferredAudioLanguagesAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetStringSettingAsync(SettingKeys.PreferredAudioLanguages, "", cancellationToken);
|
||||
|
||||
public Task SetPreferredAudioLanguagesAsync(
|
||||
string value,
|
||||
CancellationToken cancellationToken
|
||||
) => UpsertAsync(SettingKeys.PreferredAudioLanguages, value, cancellationToken);
|
||||
|
||||
public Task<bool> AreChannelNumbersEnabledAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetBoolSettingAsync(SettingKeys.ChannelNumbersEnabled, false, cancellationToken);
|
||||
|
||||
public Task SetChannelNumbersEnabledAsync(bool enabled, CancellationToken cancellationToken) =>
|
||||
UpsertAsync(
|
||||
SettingKeys.ChannelNumbersEnabled,
|
||||
enabled ? "true" : "false",
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
private async Task UpsertAsync(string key, string value, CancellationToken cancellationToken)
|
||||
{
|
||||
var existing = await dbContext.AppSettings.FirstOrDefaultAsync(
|
||||
s => s.Key == key,
|
||||
cancellationToken
|
||||
);
|
||||
if (existing is null)
|
||||
dbContext.AppSettings.Add(AppSetting.Create(key, value));
|
||||
else
|
||||
existing.SetValue(value);
|
||||
}
|
||||
}
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Settings;
|
||||
using TeleWave.Domain.Settings;
|
||||
|
||||
namespace TeleWave.Infrastructure.Settings;
|
||||
|
||||
/// <summary>Настройки сайта поверх key-value таблицы AppSetting. Запись не сохраняет сама —
|
||||
/// сохранение выполняет UnitOfWorkBehavior команды (используется общий scoped-контекст).</summary>
|
||||
public sealed class SiteSettings(IAppDbContext dbContext) : ISiteSettings
|
||||
{
|
||||
public Task<bool> IsRegistrationEnabledAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetBoolSettingAsync(SettingKeys.RegistrationEnabled, false, cancellationToken);
|
||||
|
||||
public async Task SetRegistrationEnabledAsync(bool enabled, CancellationToken cancellationToken)
|
||||
{
|
||||
await UpsertAsync(
|
||||
SettingKeys.RegistrationEnabled,
|
||||
enabled ? "true" : "false",
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
public Task<string> GetPreferredAudioLanguagesAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetStringSettingAsync(SettingKeys.PreferredAudioLanguages, "", cancellationToken);
|
||||
|
||||
public Task SetPreferredAudioLanguagesAsync(
|
||||
string value,
|
||||
CancellationToken cancellationToken
|
||||
) => UpsertAsync(SettingKeys.PreferredAudioLanguages, value, cancellationToken);
|
||||
|
||||
public Task<bool> AreChannelNumbersEnabledAsync(CancellationToken cancellationToken) =>
|
||||
dbContext.GetBoolSettingAsync(SettingKeys.ChannelNumbersEnabled, false, cancellationToken);
|
||||
|
||||
public Task SetChannelNumbersEnabledAsync(bool enabled, CancellationToken cancellationToken) =>
|
||||
UpsertAsync(
|
||||
SettingKeys.ChannelNumbersEnabled,
|
||||
enabled ? "true" : "false",
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
private async Task UpsertAsync(string key, string value, CancellationToken cancellationToken)
|
||||
{
|
||||
var existing = await dbContext.AppSettings.FirstOrDefaultAsync(
|
||||
s => s.Key == key,
|
||||
cancellationToken
|
||||
);
|
||||
if (existing is null)
|
||||
dbContext.AppSettings.Add(AppSetting.Create(key, value));
|
||||
else
|
||||
existing.SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user