mirror of
				https://github.com/Kareadita/Kavita.git
				synced 2025-11-03 19:17:05 -05:00 
			
		
		
		
	* Bump loader-utils from 2.0.2 to 2.0.3 in /UI/Web Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/webpack/loader-utils/releases) - [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.3/CHANGELOG.md) - [Commits](https://github.com/webpack/loader-utils/compare/v2.0.2...v2.0.3) --- updated-dependencies: - dependency-name: loader-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Fixed is want to read coming back as a string and not working correctly. * Changed from to Continue to be more explicit * Added the first migration which exports data as a csv in temp/. This is the backup in case data is lost in the migration. * Note for later * Fixed the migration for the series relation so when deleting any series on any edge of the relationship, the SeriesRelation row deletes. * Change buttons back to titles on series detail page * Wrote the code to import relations from the backup. * Added an additional version check to avoid file io on migration. * Code cleanup Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
		
			
				
	
	
		
			105 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Globalization;
 | 
						|
using System.IO;
 | 
						|
using System.Linq;
 | 
						|
using System.Text;
 | 
						|
using System.Threading.Tasks;
 | 
						|
using API.Entities.Enums;
 | 
						|
using CsvHelper;
 | 
						|
using Kavita.Common.EnvironmentInfo;
 | 
						|
using Microsoft.EntityFrameworkCore;
 | 
						|
using Microsoft.Extensions.Logging;
 | 
						|
 | 
						|
namespace API.Data;
 | 
						|
 | 
						|
internal sealed class SeriesRelationMigrationOutput
 | 
						|
{
 | 
						|
    public string SeriesName { get; set; }
 | 
						|
    public int SeriesId { get; set; }
 | 
						|
    public string TargetSeriesName { get; set; }
 | 
						|
    public int TargetId { get; set; }
 | 
						|
    public RelationKind Relationship { get; set; }
 | 
						|
}
 | 
						|
 | 
						|
/// <summary>
 | 
						|
/// Introduced in v0.6.1.2 and v0.7, this exports to a temp file the existing series relationships. It is a 3 part migration.
 | 
						|
/// This will run first, to export the data, then the DB migration will change the way the DB is constructed, then the last migration
 | 
						|
/// will import said file and re-construct the relationships.
 | 
						|
/// </summary>
 | 
						|
public static class MigrateSeriesRelationsExport
 | 
						|
{
 | 
						|
    private const string OutputFile = "config/relations.csv";
 | 
						|
    private const string CompleteOutputFile = "config/relations-imported.csv";
 | 
						|
    public static async Task Migrate(DataContext dataContext, ILogger<Program> logger)
 | 
						|
    {
 | 
						|
        logger.LogCritical("Running MigrateSeriesRelationsExport migration - Please be patient, this may take some time. This is not an error");
 | 
						|
        if (BuildInfo.Version > new Version(0, 6, 1, 3)
 | 
						|
            || new FileInfo(OutputFile).Exists
 | 
						|
            || new FileInfo(CompleteOutputFile).Exists)
 | 
						|
        {
 | 
						|
            logger.LogCritical("Running MigrateSeriesRelationsExport migration - complete. Nothing to do");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        var seriesWithRelationships = await dataContext.Series
 | 
						|
            .Where(s => s.Relations.Any())
 | 
						|
            .Include(s => s.Relations)
 | 
						|
            .ThenInclude(r => r.TargetSeries)
 | 
						|
            .ToListAsync();
 | 
						|
 | 
						|
        var records = new List<SeriesRelationMigrationOutput>();
 | 
						|
        var excludedRelationships = new List<RelationKind>()
 | 
						|
        {
 | 
						|
            RelationKind.Parent,
 | 
						|
        };
 | 
						|
        foreach (var series in seriesWithRelationships)
 | 
						|
        {
 | 
						|
            foreach (var relationship in series.Relations.Where(r => !excludedRelationships.Contains(r.RelationKind)))
 | 
						|
            {
 | 
						|
                records.Add(new SeriesRelationMigrationOutput()
 | 
						|
                {
 | 
						|
                    SeriesId = series.Id,
 | 
						|
                    SeriesName = series.Name,
 | 
						|
                    Relationship = relationship.RelationKind,
 | 
						|
                    TargetId = relationship.TargetSeriesId,
 | 
						|
                    TargetSeriesName = relationship.TargetSeries.Name
 | 
						|
                });
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        await using var writer = new StreamWriter(OutputFile);
 | 
						|
        await using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
 | 
						|
        {
 | 
						|
            await csv.WriteRecordsAsync(records);
 | 
						|
        }
 | 
						|
 | 
						|
        await writer.DisposeAsync();
 | 
						|
 | 
						|
        logger.LogCritical("{OutputFile} has a backup of all data", OutputFile);
 | 
						|
 | 
						|
        logger.LogCritical("Deleting all relationships in the DB. This is not an error");
 | 
						|
        var entities = await dataContext.SeriesRelation
 | 
						|
            .Include(s => s.Series)
 | 
						|
            .Include(s => s.TargetSeries)
 | 
						|
            .Select(s => s)
 | 
						|
            .ToListAsync();
 | 
						|
 | 
						|
        foreach (var seriesWithRelationship in entities)
 | 
						|
        {
 | 
						|
            logger.LogCritical("Deleting {SeriesName} --{RelationshipKind}--> {TargetSeriesName}",
 | 
						|
                seriesWithRelationship.Series.Name, seriesWithRelationship.RelationKind, seriesWithRelationship.TargetSeries.Name);
 | 
						|
            dataContext.SeriesRelation.Remove(seriesWithRelationship);
 | 
						|
 | 
						|
            await dataContext.SaveChangesAsync();
 | 
						|
        }
 | 
						|
 | 
						|
        // In case of corrupted entities (where series were deleted but their Id still existed, we delete the rest of the table)
 | 
						|
        dataContext.SeriesRelation.RemoveRange(dataContext.SeriesRelation);
 | 
						|
        await dataContext.SaveChangesAsync();
 | 
						|
 | 
						|
 | 
						|
        logger.LogCritical("Running MigrateSeriesRelationsExport migration - Completed. This is not an error");
 | 
						|
    }
 | 
						|
}
 |