using System.Collections.Generic; using System.Data; using System.Linq; using System.Text.RegularExpressions; using FluentMigrator; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration { [Migration(149)] public class convert_regex_required_tags : NzbDroneMigrationBase { public static Regex OriginalRegex = new Regex(@"^(?R|S|M|E|L|C|I|G)(_((?R)|(?RE)|(?N)){1,3})?_(?.*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); protected override void MainDbUpgrade() { Execute.WithConnection(ConvertExistingFormatTags); } private void ConvertExistingFormatTags(IDbConnection conn, IDbTransaction tran) { var updater = new CustomFormatUpdater149(conn, tran); updater.ReplaceInTags(OriginalRegex, match => { var modifiers = ""; if (match.Groups["m_n"].Success) { modifiers += "N"; } if (match.Groups["m_r"].Success) { modifiers += "RX"; } if (match.Groups["m_re"].Success) { modifiers += "RQ"; } if (modifiers != "") { modifiers = "_" + modifiers; } return $"{match.Groups["type"].Value}{modifiers}_{match.Groups["value"].Value}"; }); updater.Commit(); } } public class CustomFormat149 { public int Id { get; set; } public string Name { get; set; } public List FormatTags { get; set; } } public class CustomFormatUpdater149 { private readonly IDbConnection _connection; private readonly IDbTransaction _transaction; private List _customFormats; private HashSet _changedFormats = new HashSet(); public CustomFormatUpdater149(IDbConnection conn, IDbTransaction tran) { _connection = conn; _transaction = tran; _customFormats = GetFormats(); } public void Commit() { foreach (var profile in _changedFormats) { using (var updateProfileCmd = _connection.CreateCommand()) { updateProfileCmd.Transaction = _transaction; updateProfileCmd.CommandText = "UPDATE CustomFormats SET Name = ?, FormatTags = ? WHERE Id = ?"; updateProfileCmd.AddParameter(profile.Name); updateProfileCmd.AddParameter(profile.FormatTags.ToJson()); updateProfileCmd.AddParameter(profile.Id); updateProfileCmd.ExecuteNonQuery(); } } _changedFormats.Clear(); } public void ReplaceInTags(Regex search, string replacement) { foreach (var format in _customFormats) { format.FormatTags.ForEach(t => { search.Replace(t, replacement); }); _changedFormats.Add(format); } } public void ReplaceInTags(Regex search, MatchEvaluator evaluator) { foreach (var format in _customFormats) { format.FormatTags = format.FormatTags.Select(t => search.Replace(t, evaluator)).ToList(); _changedFormats.Add(format); } } private List GetFormats() { var profiles = new List(); using (var getProfilesCmd = _connection.CreateCommand()) { getProfilesCmd.Transaction = _transaction; getProfilesCmd.CommandText = @"SELECT Id, Name, FormatTags FROM CustomFormats"; using (var profileReader = getProfilesCmd.ExecuteReader()) { while (profileReader.Read()) { profiles.Add(new CustomFormat149 { Id = profileReader.GetInt32(0), Name = profileReader.GetString(1), FormatTags = Json.Deserialize>(profileReader.GetString(2)) }); } } } return profiles; } } }