using System.Collections.Generic; using System.Data; using System.Linq; using Dapper; using FluentMigrator; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration { [Migration(71)] public class unknown_quality_in_profile : NzbDroneMigrationBase { protected override void MainDbUpgrade() { Delete.Column("Weight").FromTable("QualityDefinitions"); Execute.WithConnection(ConvertProfile); } private void ConvertProfile(IDbConnection conn, IDbTransaction tran) { var updater = new ProfileUpdater71(conn, tran); updater.PrependQuality(0); updater.Commit(); } } public class Profile71 { public int Id { get; set; } public string Name { get; set; } public int Cutoff { get; set; } public List Items { get; set; } public int Language { get; set; } } public class ProfileItem71 { public int Quality { get; set; } public bool Allowed { get; set; } } public class ProfileUpdater71 { private readonly IDbConnection _connection; private readonly IDbTransaction _transaction; private List _profiles; private HashSet _changedProfiles = new HashSet(); public ProfileUpdater71(IDbConnection conn, IDbTransaction tran) { _connection = conn; _transaction = tran; _profiles = GetProfiles(); } public void Commit() { var profilesToUpdate = _changedProfiles.Select(p => new { Id = p.Id, Name = p.Name, Cutoff = p.Cutoff, Language = p.Language, Items = p.Items.ToJson() }); var updateSql = $"UPDATE \"Profiles\" SET \"Name\" = @Name, \"Cutoff\" = @Cutoff, \"Language\" = @Language, \"Items\" = @Items WHERE \"Id\" = @Id"; _connection.Execute(updateSql, profilesToUpdate, transaction: _transaction); _changedProfiles.Clear(); } public void PrependQuality(int quality) { foreach (var profile in _profiles) { if (profile.Items.Any(v => v.Quality == quality)) { continue; } profile.Items.Insert(0, new ProfileItem71 { Quality = quality, Allowed = false }); _changedProfiles.Add(profile); } } public void AppendQuality(int quality) { foreach (var profile in _profiles) { if (profile.Items.Any(v => v.Quality == quality)) { continue; } profile.Items.Add(new ProfileItem71 { Quality = quality, Allowed = false }); _changedProfiles.Add(profile); } } public void SplitQualityPrepend(int find, int quality) { foreach (var profile in _profiles) { if (profile.Items.Any(v => v.Quality == quality)) { continue; } var findIndex = profile.Items.FindIndex(v => v.Quality == find); profile.Items.Insert(findIndex, new ProfileItem71 { Quality = quality, Allowed = profile.Items[findIndex].Allowed }); if (profile.Cutoff == find) { profile.Cutoff = quality; } _changedProfiles.Add(profile); } } public void SplitQualityAppend(int find, int quality) { foreach (var profile in _profiles) { if (profile.Items.Any(v => v.Quality == quality)) { continue; } var findIndex = profile.Items.FindIndex(v => v.Quality == find); profile.Items.Insert(findIndex + 1, new ProfileItem71 { Quality = quality, Allowed = false }); _changedProfiles.Add(profile); } } private List GetProfiles() { var profiles = new List(); using (var getProfilesCmd = _connection.CreateCommand()) { getProfilesCmd.Transaction = _transaction; getProfilesCmd.CommandText = "SELECT \"Id\", \"Name\", \"Cutoff\", \"Items\", \"Language\" FROM \"Profiles\""; using (var profileReader = getProfilesCmd.ExecuteReader()) { while (profileReader.Read()) { profiles.Add(new Profile71 { Id = profileReader.GetInt32(0), Name = profileReader.GetString(1), Cutoff = profileReader.GetInt32(2), Items = Json.Deserialize>(profileReader.GetString(3)), Language = profileReader.GetInt32(4) }); } } } return profiles; } } }