From bdb1076100c576ea99d36ed81d156366a642ea1f Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 13 Feb 2016 22:23:37 +0100 Subject: [PATCH] Updated db migration testing framework so we only run migrations up to the one we're testing. fixes #902 --- .../Migration/070_delay_profileFixture.cs | 28 ++- .../071_unknown_quality_in_profileFixture.cs | 17 +- ...re.cs => 072_history_downloadIdFixture.cs} | 38 ++-- .../Migration/075_force_lib_updateFixture.cs | 22 ++- .../Migration/079_dedupe_tagsFixture.cs | 38 ++-- ..._prefix_to_transmission_categoryFixture.cs | 41 ++--- .../084_update_quality_minmax_sizeFixture.cs | 43 ++--- .../085_expand_transmission_urlbaseFixture.cs | 42 ++--- .../086_pushbullet_device_idsFixture.cs | 25 ++- ...ushbullet_devices_channels_listFixture.cs} | 12 +- .../090_update_kickass_urlFixture.cs | 18 +- src/NzbDrone.Core.Test/Framework/DbTest.cs | 64 +------ .../Framework/DirectDataMapper.cs | 130 ++++++++++++++ .../Framework/MigrationTest.cs | 34 +++- .../Framework/TestDatabase.cs | 69 +++++++ .../Framework/TestDbHelper.cs | 7 - .../NzbDrone.Core.Test.csproj | 7 +- src/NzbDrone.Core/Datastore/DbFactory.cs | 16 +- .../Datastore/Migration/070_delay_profile.cs | 47 +++-- .../071_unknown_quality_in_profile.cs | 170 +++++++++++++----- .../Datastore/Migration/072_history_grabid.cs | 15 +- .../Migration/075_force_lib_update.cs | 11 +- ...ove_dot_prefix_to_transmission_category.cs | 38 ++++ .../084_update_quality_minmax_size.cs | 9 + .../085_expand_transmission_urlbase.cs | 12 ++ .../Migration/086_pushbullet_device_ids.cs | 24 ++- .../088_pushbullet_devices_channels_list.cs | 8 + .../Migration/090_update_kickass_url.cs | 18 ++ .../Migration/Framework/MigrationContext.cs | 8 +- .../Framework/MigrationController.cs | 26 ++- 30 files changed, 707 insertions(+), 330 deletions(-) rename src/NzbDrone.Core.Test/Datastore/Migration/{072_history_grabIdFixture.cs => 072_history_downloadIdFixture.cs} (63%) rename src/NzbDrone.Core.Test/Datastore/Migration/{088_pushbullet_devices_channels.cs => 088_pushbullet_devices_channels_listFixture.cs} (68%) create mode 100644 src/NzbDrone.Core.Test/Framework/DirectDataMapper.cs create mode 100644 src/NzbDrone.Core.Test/Framework/TestDatabase.cs delete mode 100644 src/NzbDrone.Core.Test/Framework/TestDbHelper.cs diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/070_delay_profileFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/070_delay_profileFixture.cs index 7a73d1074..be2b07b66 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/070_delay_profileFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/070_delay_profileFixture.cs @@ -2,11 +2,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Datastore.Migration; -using NzbDrone.Core.Indexers; -using NzbDrone.Core.Profiles.Delay; -using NzbDrone.Core.Tags; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.Datastore.Migration { @@ -16,7 +12,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_migrate_old_delays() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Profiles").Row(new { @@ -35,10 +31,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var allProfiles = Mocker.Resolve().All().ToList(); + var allProfiles = db.Query("SELECT * FROM DelayProfiles"); allProfiles.Should().HaveCount(3); - allProfiles.Should().OnlyContain(c => c.PreferredProtocol == DownloadProtocol.Usenet); + allProfiles.Should().OnlyContain(c => c.PreferredProtocol == 1); allProfiles.Should().OnlyContain(c => c.TorrentDelay == 0); allProfiles.Should().Contain(c => c.UsenetDelay == 60); allProfiles.Should().Contain(c => c.UsenetDelay == 120); @@ -47,17 +43,18 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_create_tag_for_delay_profile() { - WithTestDb(c => + var db = WithMigrationTestDb(c => + { c.Insert.IntoTable("Profiles").Row(new { GrabDelay = 1, Name = "OneHour", Cutoff = 0, Items = "[]" - }) - ); + }); + }); - var tags = Mocker.Resolve().All().ToList(); + var tags = db.Query("SELECT * FROM Tags"); tags.Should().HaveCount(1); tags.First().Label.Should().Be("delay-60"); @@ -66,7 +63,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_add_tag_to_series_that_had_a_profile_with_delay_attached() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Profiles").Row(new { @@ -95,12 +92,11 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var tag = Mocker.Resolve().All().ToList().First(); - var series = Mocker.Resolve().All().ToList(); + var tag = db.Query("SELECT Id, Label FROM Tags").Single(); + var series = db.Query("SELECT Tags FROM Series"); series.Should().HaveCount(1); - series.First().Tags.Should().HaveCount(1); - series.First().Tags.First().Should().Be(tag.Id); + series.First().Tags.Should().BeEquivalentTo(tag.Id); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/071_unknown_quality_in_profileFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/071_unknown_quality_in_profileFixture.cs index 4a85016c2..ad31df44c 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/071_unknown_quality_in_profileFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/071_unknown_quality_in_profileFixture.cs @@ -2,12 +2,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Datastore.Migration; -using NzbDrone.Core.Indexers; -using NzbDrone.Core.Profiles; -using NzbDrone.Core.Profiles.Delay; -using NzbDrone.Core.Tags; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.Datastore.Migration { @@ -17,10 +12,11 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_add_unknown_to_old_profile() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Profiles").Row(new { + Id = 0, Name = "SDTV", Cutoff = 1, Items = "[ { \"quality\": 1, \"allowed\": true } ]", @@ -28,11 +24,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var allProfiles = Mocker.Resolve().All().ToList(); + var profiles = db.Query("SELECT Items FROM Profiles LIMIT 1"); - allProfiles.Should().HaveCount(1); - allProfiles.First().Items.Should().HaveCount(2); - allProfiles.First().Items.Should().Contain(i => i.Quality.Id == 0 && i.Allowed == false); + var items = profiles.First().Items; + items.Should().HaveCount(2); + items.First().Quality.Should().Be(0); + items.First().Allowed.Should().Be(false); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/072_history_grabIdFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/072_history_downloadIdFixture.cs similarity index 63% rename from src/NzbDrone.Core.Test/Datastore/Migration/072_history_grabIdFixture.cs rename to src/NzbDrone.Core.Test/Datastore/Migration/072_history_downloadIdFixture.cs index 9a85f3e26..c976f9b10 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/072_history_grabIdFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/072_history_downloadIdFixture.cs @@ -6,7 +6,6 @@ using FluentMigrator; using NUnit.Framework; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration; -using NzbDrone.Core.History; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Datastore.Migration @@ -17,7 +16,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_move_grab_id_from_date_to_columns() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { InsertHistory(c, new Dictionary { @@ -33,19 +32,19 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); - var allProfiles = Mocker.Resolve().All().ToList(); + var history = db.Query("SELECT DownloadId, Data FROM History"); - allProfiles.Should().HaveCount(2); - allProfiles.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); - allProfiles.Should().Contain(c => c.DownloadId == "123"); - allProfiles.Should().Contain(c => c.DownloadId == "abc"); + history.Should().HaveCount(2); + history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); + history.Should().Contain(c => c.DownloadId == "123"); + history.Should().Contain(c => c.DownloadId == "abc"); } [Test] public void should_leave_items_with_no_grabid() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { InsertHistory(c, new Dictionary { @@ -60,18 +59,18 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); - var allProfiles = Mocker.Resolve().All().ToList(); + var history = db.Query("SELECT DownloadId, Data FROM History"); - allProfiles.Should().HaveCount(2); - allProfiles.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); - allProfiles.Should().Contain(c => c.DownloadId == "123"); - allProfiles.Should().Contain(c => c.DownloadId == null); + history.Should().HaveCount(2); + history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); + history.Should().Contain(c => c.DownloadId == "123"); + history.Should().Contain(c => c.DownloadId == null); } [Test] public void should_leave_other_data() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { InsertHistory(c, new Dictionary { @@ -81,16 +80,15 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var allProfiles = Mocker.Resolve().All().Single(); + var history = db.Query("SELECT DownloadId, Data FROM History").Single(); - allProfiles.Data.Should().NotContainKey("downloadClientId"); - allProfiles.Data.Should().Contain(new KeyValuePair("indexer", "test")); - allProfiles.Data.Should().Contain(new KeyValuePair("group", "test2")); + history.Data.Should().NotContainKey("downloadClientId"); + history.Data.Should().Contain(new KeyValuePair("indexer", "test")); + history.Data.Should().Contain(new KeyValuePair("group", "test2")); - allProfiles.DownloadId.Should().Be("123"); + history.DownloadId.Should().Be("123"); } - private void InsertHistory(MigrationBase migrationBase, Dictionary data) { migrationBase.Insert.IntoTable("History").Row(new diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/075_force_lib_updateFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/075_force_lib_updateFixture.cs index fabf8ebcb..1d6c113b8 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/075_force_lib_updateFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/075_force_lib_updateFixture.cs @@ -1,29 +1,28 @@ using System.Linq; using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.Jobs; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Datastore.Migration; namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class force_lib_updateFixture : MigrationTest + public class force_lib_updateFixture : MigrationTest { [Test] public void should_not_fail_on_empty_db() { - WithTestDb(c => { }); + var db = WithMigrationTestDb(); - Mocker.Resolve().All().Should().BeEmpty(); - Mocker.Resolve().All().Should().BeEmpty(); + db.Query("SELECT * FROM ScheduledTasks").Should().BeEmpty(); + db.Query("SELECT * FROM Series").Should().BeEmpty(); } [Test] public void should_reset_job_last_execution_time() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("ScheduledTasks").Row(new { @@ -40,7 +39,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var jobs = Mocker.Resolve().All().ToList(); + var jobs = db.Query("SELECT TypeName, LastExecution FROM ScheduledTasks"); jobs.Single(c => c.TypeName == "NzbDrone.Core.Tv.Commands.RefreshSeriesCommand") .LastExecution.Year.Should() @@ -51,11 +50,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration .Be(2000); } - [Test] public void should_reset_series_last_sync_time() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Series").Row(new { @@ -92,9 +90,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var jobs = Mocker.Resolve().All().ToList(); + var series = db.Query("SELECT LastInfoSync FROM Series"); - jobs.Should().OnlyContain(c => c.LastInfoSync.Value.Year == 2014); + series.Should().OnlyContain(c => c.LastInfoSync.Value.Year == 2014); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/079_dedupe_tagsFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/079_dedupe_tagsFixture.cs index c7f01bf57..e333fb9a1 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/079_dedupe_tagsFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/079_dedupe_tagsFixture.cs @@ -1,21 +1,18 @@ -using System; -using System.Linq; +using System.Linq; using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.Jobs; -using NzbDrone.Core.Tags; +using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class dedupe_tagsFixture : MigrationTest + public class dedupe_tagsFixture : MigrationTest { [Test] public void should_not_fail_if_series_tags_are_null() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Series").Row(new { @@ -40,13 +37,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Mocker.Resolve().All().Should().HaveCount(1); + var tags = db.Query("SELECT * FROM Tags"); + tags.Should().HaveCount(1); } [Test] public void should_not_fail_if_series_tags_are_empty() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Series").Row(new { @@ -72,13 +70,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Mocker.Resolve().All().Should().HaveCount(1); + var tags = db.Query("SELECT * FROM Tags"); + tags.Should().HaveCount(1); } [Test] public void should_remove_duplicate_labels_from_tags() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Tags").Row(new { @@ -91,13 +90,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Mocker.Resolve().All().Should().HaveCount(1); + var tags = db.Query("SELECT * FROM Tags"); + tags.Should().HaveCount(1); } [Test] public void should_not_allow_duplicate_tag_to_be_inserted() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Tags").Row(new { @@ -105,13 +105,13 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Assert.That(() => Mocker.Resolve().Insert(new Tag { Label = "test" }), Throws.Exception); + Assert.That(() => db.Query("INSERT INTO Tags (Label) VALUES ('test')"), Throws.Exception); } [Test] public void should_replace_duplicated_tag_with_proper_tag() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Series").Row(new { @@ -142,13 +142,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Mocker.Resolve().Get(1).Tags.First().Should().Be(1); + var series = db.Query("SELECT Tags FROM Series WHERE Id = 1").Single(); + series.Tags.First().Should().Be(1); } [Test] public void should_only_update_affected_series() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Series").Row(new { @@ -197,7 +198,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - Mocker.Resolve().Get(2).Tags.Should().BeEmpty(); + var series = db.Query("SELECT Tags FROM Series WHERE Id = 2").Single(); + series.Tags.Should().BeEmpty(); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/081_move_dot_prefix_to_transmission_categoryFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/081_move_dot_prefix_to_transmission_categoryFixture.cs index 372984568..afb06264b 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/081_move_dot_prefix_to_transmission_categoryFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/081_move_dot_prefix_to_transmission_categoryFixture.cs @@ -3,27 +3,25 @@ using System.Linq; using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; -using NzbDrone.Core.Download; -using NzbDrone.Core.Download.Clients.Sabnzbd; -using NzbDrone.Core.Download.Clients.Transmission; using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Datastore.Migration; namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class move_dot_prefix_to_transmission_categoryFixture : MigrationTest + public class move_dot_prefix_to_transmission_categoryFixture : MigrationTest { [Test] public void should_not_fail_if_no_transmission() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { - c.Insert.IntoTable("DownloadClients").Row(new + c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Sab", Implementation = "Sabnzbd", - Settings = new SabnzbdSettings + Settings = new { Host = "127.0.0.1", TvCategory = "abc" @@ -32,24 +30,23 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); - - items.Should().HaveCount(1); + var downloadClients = db.Query("SELECT Settings FROM DownloadClients"); - items.First().Settings.As().TvCategory.Should().Be("abc"); + downloadClients.Should().HaveCount(1); + downloadClients.First().Settings.ToObject().TvCategory.Should().Be("abc"); } [Test] public void should_be_updated_for_transmission() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Trans", Implementation = "Transmission", - Settings = new TransmissionSettings + Settings = new { Host = "127.0.0.1", TvCategory = "abc" @@ -58,24 +55,23 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var downloadClients = db.Query("SELECT Settings FROM DownloadClients"); - items.Should().HaveCount(1); - - items.First().Settings.As().TvCategory.Should().Be(".abc"); + downloadClients.Should().HaveCount(1); + downloadClients.First().Settings.ToObject().TvCategory.Should().Be(".abc"); } [Test] public void should_leave_empty_category_untouched() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Trans", Implementation = "Transmission", - Settings = new TransmissionSettings + Settings = new { Host = "127.0.0.1", TvCategory = "" @@ -84,11 +80,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); - - items.Should().HaveCount(1); + var downloadClients = db.Query("SELECT Settings FROM DownloadClients"); - items.First().Settings.As().TvCategory.Should().Be(""); + downloadClients.Should().HaveCount(1); + downloadClients.First().Settings.ToObject().TvCategory.Should().Be(""); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/084_update_quality_minmax_sizeFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/084_update_quality_minmax_sizeFixture.cs index 556bb60dd..8b4b237e6 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/084_update_quality_minmax_sizeFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/084_update_quality_minmax_sizeFixture.cs @@ -1,32 +1,28 @@ -using System; -using System.Linq; +using System.Linq; using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.Qualities; +using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class update_quality_minmax_sizeFixture : MigrationTest + public class update_quality_minmax_sizeFixture : MigrationTest { [Test] public void should_not_fail_if_empty() { - WithTestDb(c => - { - - }); + var db = WithMigrationTestDb(); - var items = Mocker.Resolve().All(); + var qualityDefinitions = db.Query("SELECT * FROM QualityDefinitions"); - items.Should().HaveCount(0); + qualityDefinitions.Should().BeEmpty(); } [Test] public void should_set_rawhd_to_null() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("QualityDefinitions").Row(new { @@ -44,17 +40,16 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var qualityDefinitions = db.Query("SELECT * FROM QualityDefinitions"); - items.Should().HaveCount(2); - - items.First(v => v.Quality.Id == 10).MaxSize.Should().NotHaveValue(); + qualityDefinitions.Should().HaveCount(2); + qualityDefinitions.First(v => v.Quality == 10).MaxSize.Should().NotHaveValue(); } [Test] public void should_set_zero_maxsize_to_null() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("QualityDefinitions").Row(new { @@ -65,17 +60,16 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); - - items.Should().HaveCount(1); + var qualityDefinitions = db.Query("SELECT * FROM QualityDefinitions"); - items.First(v => v.Quality.Id == 1).MaxSize.Should().NotHaveValue(); + qualityDefinitions.Should().HaveCount(1); + qualityDefinitions.First(v => v.Quality == 1).MaxSize.Should().NotHaveValue(); } [Test] public void should_preserve_values() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("QualityDefinitions").Row(new { @@ -93,11 +87,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); - - items.Should().HaveCount(2); + var qualityDefinitions = db.Query("SELECT * FROM QualityDefinitions"); - items.First(v => v.Quality.Id == 1).MaxSize.Should().Be(100); + qualityDefinitions.Should().HaveCount(2); + qualityDefinitions.First(v => v.Quality == 1).MaxSize.Should().Be(100); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/085_expand_transmission_urlbaseFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/085_expand_transmission_urlbaseFixture.cs index cd43a1907..0b1f7460d 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/085_expand_transmission_urlbaseFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/085_expand_transmission_urlbaseFixture.cs @@ -1,30 +1,26 @@ -using System; -using System.Linq; +using System.Linq; using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; -using NzbDrone.Core.Download; -using NzbDrone.Core.Download.Clients.Deluge; -using NzbDrone.Core.Download.Clients.Sabnzbd; -using NzbDrone.Core.Download.Clients.Transmission; +using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Test.Framework; -using System.Drawing; + namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class expand_transmission_urlbaseFixture : MigrationTest + public class expand_transmission_urlbaseFixture : MigrationTest { [Test] public void should_not_fail_if_no_transmission() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Deluge", Implementation = "Deluge", - Settings = new DelugeSettings + Settings = new DelugeSettings85 { Host = "127.0.0.1", TvCategory = "abc", @@ -34,51 +30,48 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM DownloadClients"); items.Should().HaveCount(1); - - items.First().Settings.As().UrlBase.Should().Be("/my/"); + items.First().Settings.ToObject().UrlBase.Should().Be("/my/"); } [Test] public void should_be_updated_for_transmission() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Trans", Implementation = "Transmission", - Settings = new TransmissionSettings + Settings = new TransmissionSettings81 { Host = "127.0.0.1", - TvCategory = "abc", - UrlBase = null + TvCategory = "abc" }.ToJson(), ConfigContract = "TransmissionSettings" }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM DownloadClients"); items.Should().HaveCount(1); - - items.First().Settings.As().UrlBase.Should().Be("/transmission/"); + items.First().Settings.ToObject().UrlBase.Should().Be("/transmission/"); } [Test] public void should_be_append_to_existing_urlbase() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("DownloadClients").Row(new { Enable = 1, Name = "Trans", Implementation = "Transmission", - Settings = new TransmissionSettings + Settings = new TransmissionSettings81 { Host = "127.0.0.1", TvCategory = "abc", @@ -88,11 +81,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM DownloadClients"); items.Should().HaveCount(1); - - items.First().Settings.As().UrlBase.Should().Be("/my/url/transmission/"); + items.First().Settings.ToObject().UrlBase.Should().Be("/my/url/transmission/"); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs index 846889c6f..20a8e063a 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs @@ -2,19 +2,18 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; -using NzbDrone.Core.Notifications; -using NzbDrone.Core.Notifications.PushBullet; -using NzbDrone.Core.Notifications.Pushover; +using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Test.Framework; + namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class pushbullet_device_idsFixture : MigrationTest + public class pushbullet_device_idsFixture : MigrationTest { [Test] public void should_not_fail_if_no_pushbullet() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Notifications").Row(new { @@ -23,12 +22,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration OnUpgrade = false, Name = "Pushover", Implementation = "Pushover", - Settings = new PushoverSettings().ToJson(), + Settings = "{}", ConfigContract = "PushoverSettings" }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM Notifications"); items.Should().HaveCount(1); } @@ -36,7 +35,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration [Test] public void should_not_fail_if_deviceId_is_not_set() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Notifications").Row(new { @@ -47,13 +46,13 @@ namespace NzbDrone.Core.Test.Datastore.Migration Implementation = "PushBullet", Settings = new { - ApiKey = "my_api_key", + ApiKey = "my_api_key" }.ToJson(), ConfigContract = "PushBulletSettings" }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM Notifications"); items.Should().HaveCount(1); } @@ -63,7 +62,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration { var deviceId = "device_id"; - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Notifications").Row(new { @@ -81,10 +80,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM Notifications"); items.Should().HaveCount(1); - items.First().Settings.As().DeviceIds.First().Should().Be(deviceId); + items.First().Settings.ToObject().DeviceIds.First().Should().Be(deviceId); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels.cs b/src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels_listFixture.cs similarity index 68% rename from src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels.cs rename to src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels_listFixture.cs index 7ace6dad2..37679998c 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/088_pushbullet_devices_channels_listFixture.cs @@ -2,19 +2,18 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; -using NzbDrone.Core.Notifications; -using NzbDrone.Core.Notifications.PushBullet; +using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Datastore.Migration { [TestFixture] - public class pushbullet_devices_channels : MigrationTest + public class pushbullet_devices_channels_listFixture : MigrationTest { [Test] public void should_convert_comma_separted_string_to_list() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Notifications").Row(new { @@ -32,11 +31,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All(); + var items = db.Query("SELECT * FROM Notifications"); items.Should().HaveCount(1); - var settings = items.First().Settings.As(); - settings.ChannelTags.Should().HaveCount(2); + items.First().Settings.ToObject().ChannelTags.Should().HaveCount(2); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/090_update_kickass_urlFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/090_update_kickass_urlFixture.cs index b3e97b6c9..292344127 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/090_update_kickass_urlFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/090_update_kickass_urlFixture.cs @@ -3,8 +3,6 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration; -using NzbDrone.Core.Indexers; -using NzbDrone.Core.Indexers.KickassTorrents; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.Datastore.Migration @@ -20,13 +18,13 @@ namespace NzbDrone.Core.Test.Datastore.Migration // [TestCase("HTTP://KICKASS.SO")] Not sure if there is an easy way to do this, not sure if worth it. public void should_replace_old_url(string oldUrl) { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Indexers").Row(new { Name = "Kickass_wrong_url", Implementation = "KickassTorrents", - Settings = new KickassTorrentsSettings + Settings = new KickassTorrentsSettings90 { BaseUrl = oldUrl }.ToJson(), @@ -34,22 +32,22 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All().ToList(); + var items = db.Query("SELECT * FROM Indexers"); items.Should().HaveCount(1); - items.First().Settings.As().BaseUrl.Should().Be("https://kat.cr"); + items.First().Settings.ToObject().BaseUrl.Should().Be("https://kat.cr"); } [Test] public void should_not_replace_other_indexers() { - WithTestDb(c => + var db = WithMigrationTestDb(c => { c.Insert.IntoTable("Indexers").Row(new { Name = "not_kickass", Implementation = "NotKickassTorrents", - Settings = new KickassTorrentsSettings + Settings = new KickassTorrentsSettings90 { BaseUrl = "kickass.so", }.ToJson(), @@ -57,10 +55,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration }); }); - var items = Mocker.Resolve().All().ToList(); + var items = db.Query("SELECT * FROM Indexers"); items.Should().HaveCount(1); - items.First().Settings.As().BaseUrl.Should().Be("kickass.so"); + items.First().Settings.ToObject().BaseUrl.Should().Be("kickass.so"); } } } diff --git a/src/NzbDrone.Core.Test/Framework/DbTest.cs b/src/NzbDrone.Core.Test/Framework/DbTest.cs index 3e6eb8f43..ae59fbe23 100644 --- a/src/NzbDrone.Core.Test/Framework/DbTest.cs +++ b/src/NzbDrone.Core.Test/Framework/DbTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data; using System.IO; using System.Linq; using FluentMigrator; @@ -7,11 +8,11 @@ using FluentMigrator.Runner; using Marr.Data; using Moq; using NUnit.Framework; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Messaging.Events; - namespace NzbDrone.Core.Test.Framework { public abstract class DbTest : DbTest @@ -70,7 +71,6 @@ namespace NzbDrone.Core.Test.Framework get { return MigrationType.Main; - } } @@ -85,10 +85,10 @@ namespace NzbDrone.Core.Test.Framework } } - protected virtual TestDatabase WithTestDb(Action beforeMigration) + protected virtual ITestDatabase WithTestDb(MigrationContext migrationContext) { var factory = Mocker.Resolve(); - var database = factory.Create(MigrationType, beforeMigration); + var database = factory.Create(migrationContext); Mocker.SetConstant(database); switch (MigrationType) @@ -118,7 +118,6 @@ namespace NzbDrone.Core.Test.Framework return testDb; } - protected void SetupContainer() { WithTempAsAppPath(); @@ -134,7 +133,7 @@ namespace NzbDrone.Core.Test.Framework public virtual void SetupDb() { SetupContainer(); - _db = WithTestDb(null); + _db = WithTestDb(new MigrationContext(MigrationType)); } [TearDown] @@ -158,57 +157,4 @@ namespace NzbDrone.Core.Test.Framework } } } - - - public interface ITestDatabase - { - void InsertMany(IEnumerable items) where T : ModelBase, new(); - T Insert(T item) where T : ModelBase, new(); - List All() where T : ModelBase, new(); - T Single() where T : ModelBase, new(); - void Update(T childModel) where T : ModelBase, new(); - void Delete(T childModel) where T : ModelBase, new(); - } - - public class TestDatabase : ITestDatabase - { - private readonly IDatabase _dbConnection; - private IEventAggregator _eventAggregator; - - public TestDatabase(IDatabase dbConnection) - { - _eventAggregator = new Mock().Object; - _dbConnection = dbConnection; - } - - public void InsertMany(IEnumerable items) where T : ModelBase, new() - { - new BasicRepository(_dbConnection, _eventAggregator).InsertMany(items.ToList()); - } - - public T Insert(T item) where T : ModelBase, new() - { - return new BasicRepository(_dbConnection, _eventAggregator).Insert(item); - } - - public List All() where T : ModelBase, new() - { - return new BasicRepository(_dbConnection, _eventAggregator).All().ToList(); - } - - public T Single() where T : ModelBase, new() - { - return All().SingleOrDefault(); - } - - public void Update(T childModel) where T : ModelBase, new() - { - new BasicRepository(_dbConnection, _eventAggregator).Update(childModel); - } - - public void Delete(T childModel) where T : ModelBase, new() - { - new BasicRepository(_dbConnection, _eventAggregator).Delete(childModel); - } - } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/Framework/DirectDataMapper.cs b/src/NzbDrone.Core.Test/Framework/DirectDataMapper.cs new file mode 100644 index 000000000..27b4354c1 --- /dev/null +++ b/src/NzbDrone.Core.Test/Framework/DirectDataMapper.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Test.Framework +{ + public interface IDirectDataMapper + { + List> Query(string sql); + List Query(string sql) where T : new(); + } + + public class DirectDataMapper : IDirectDataMapper + { + private readonly DbProviderFactory _providerFactory; + private readonly string _connectionString; + + public DirectDataMapper(IDatabase database) + { + var dataMapper = database.GetDataMapper(); + _providerFactory = dataMapper.ProviderFactory; + _connectionString = dataMapper.ConnectionString; + } + + private DbConnection OpenConnection() + { + var connection = _providerFactory.CreateConnection(); + connection.ConnectionString = _connectionString; + connection.Open(); + return connection; + } + + public DataTable GetDataTable(string sql) + { + using (var connection = OpenConnection()) + { + using (var cmd = connection.CreateCommand()) + { + var dataTable = new DataTable(); + cmd.CommandText = sql; + dataTable.Load(cmd.ExecuteReader()); + return dataTable; + } + } + } + + public List> Query(string sql) + { + var dataTable = GetDataTable(sql); + + return dataTable.Rows.Cast().Select(MapToDictionary).ToList(); + } + + public List Query(string sql) where T : new() + { + var dataTable = GetDataTable(sql); + + return dataTable.Rows.Cast().Select(MapToObject).ToList(); + } + + protected Dictionary MapToDictionary(DataRow dataRow) + { + var item = new Dictionary(); + + for (var i = 0; i < dataRow.Table.Columns.Count; i++) + { + var columnName = dataRow.Table.Columns[i].ColumnName; + + object value; + if (dataRow.ItemArray[i] == DBNull.Value) + { + value = null; + } + else + { + value = dataRow.ItemArray[i]; + } + + item[columnName] = dataRow.ItemArray[i]; + } + + return item; + } + + protected T MapToObject(DataRow dataRow) where T : new() + { + var item = new T(); + + for (var i = 0; i < dataRow.Table.Columns.Count; i++) + { + var columnName = dataRow.Table.Columns[i].ColumnName; + var propertyInfo = typeof(T).GetProperty(columnName); + + if (propertyInfo == null) + { + throw new Exception(string.Format("Column {0} doesn't exist on type {1}.", columnName, typeof(T))); + } + + var propertyType = propertyInfo.PropertyType; + + if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + propertyType = propertyType.GetGenericArguments()[0]; + } + + object value; + if (dataRow.ItemArray[i] == DBNull.Value) + { + value = null; + } + else if (dataRow.Table.Columns[i].DataType == typeof(string) && propertyType != typeof(string)) + { + value = Json.Deserialize((string)dataRow.ItemArray[i], propertyType); + } + else + { + value = Convert.ChangeType(dataRow.ItemArray[i], propertyType); + } + + propertyInfo.SetValue(item, value, null); + } + + return item; + } + } +} diff --git a/src/NzbDrone.Core.Test/Framework/MigrationTest.cs b/src/NzbDrone.Core.Test/Framework/MigrationTest.cs index fd610c693..1a49bedfd 100644 --- a/src/NzbDrone.Core.Test/Framework/MigrationTest.cs +++ b/src/NzbDrone.Core.Test/Framework/MigrationTest.cs @@ -1,23 +1,41 @@ using System; +using System.Data; using FluentMigrator; using NUnit.Framework; using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore.Migration.Framework; +using NzbDrone.Test.Common.AutoMoq; namespace NzbDrone.Core.Test.Framework { [Category("DbMigrationTest")] [Category("DbTest")] - public abstract class MigrationTest : DbTest where TMigration : MigrationBase + public abstract class MigrationTest : DbTest where TMigration : NzbDroneMigrationBase { - protected override TestDatabase WithTestDb(Action beforeMigration) + protected long MigrationVersion { - return base.WithTestDb(m => + get { - if (m.GetType() == typeof(TMigration)) + var attrib = (MigrationAttribute)Attribute.GetCustomAttribute(typeof(TMigration), typeof(MigrationAttribute)); + return attrib.Version; + } + } + + protected virtual IDirectDataMapper WithMigrationTestDb(Action beforeMigration = null) + { + var db = WithTestDb(new MigrationContext(MigrationType, MigrationVersion) + { + BeforeMigration = m => { - beforeMigration(m); + var migration = m as TMigration; + if (beforeMigration != null && migration is TMigration) + { + beforeMigration(migration); + } } }); + + return db.GetDirectDataMapper(); } [SetUp] @@ -25,5 +43,11 @@ namespace NzbDrone.Core.Test.Framework { SetupContainer(); } + + [Obsolete("Don't use Mocker/Repositories in MigrationTests, query the DB.", true)] + public new AutoMoqer Mocker + { + get { return base.Mocker; } + } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/Framework/TestDatabase.cs b/src/NzbDrone.Core.Test/Framework/TestDatabase.cs new file mode 100644 index 000000000..b982bbdef --- /dev/null +++ b/src/NzbDrone.Core.Test/Framework/TestDatabase.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using Moq; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.Test.Framework +{ + public interface ITestDatabase + { + void InsertMany(IEnumerable items) where T : ModelBase, new(); + T Insert(T item) where T : ModelBase, new(); + List All() where T : ModelBase, new(); + T Single() where T : ModelBase, new(); + void Update(T childModel) where T : ModelBase, new(); + void Delete(T childModel) where T : ModelBase, new(); + IDirectDataMapper GetDirectDataMapper(); + } + + public class TestDatabase : ITestDatabase + { + private readonly IDatabase _dbConnection; + private readonly IEventAggregator _eventAggregator; + + public TestDatabase(IDatabase dbConnection) + { + _eventAggregator = new Mock().Object; + _dbConnection = dbConnection; + } + + public void InsertMany(IEnumerable items) where T : ModelBase, new() + { + new BasicRepository(_dbConnection, _eventAggregator).InsertMany(items.ToList()); + } + + public T Insert(T item) where T : ModelBase, new() + { + return new BasicRepository(_dbConnection, _eventAggregator).Insert(item); + } + + public List All() where T : ModelBase, new() + { + return new BasicRepository(_dbConnection, _eventAggregator).All().ToList(); + } + + public T Single() where T : ModelBase, new() + { + return All().SingleOrDefault(); + } + + public void Update(T childModel) where T : ModelBase, new() + { + new BasicRepository(_dbConnection, _eventAggregator).Update(childModel); + } + + public void Delete(T childModel) where T : ModelBase, new() + { + new BasicRepository(_dbConnection, _eventAggregator).Delete(childModel); + } + + public IDirectDataMapper GetDirectDataMapper() + { + return new DirectDataMapper(_dbConnection); + } + } +} diff --git a/src/NzbDrone.Core.Test/Framework/TestDbHelper.cs b/src/NzbDrone.Core.Test/Framework/TestDbHelper.cs deleted file mode 100644 index b71ef9f0f..000000000 --- a/src/NzbDrone.Core.Test/Framework/TestDbHelper.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NzbDrone.Core.Test.Framework -{ - internal static class TestDbHelper - { - - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index b7845a57a..138cf015f 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -120,9 +120,9 @@ - + - + @@ -186,9 +186,10 @@ + - + diff --git a/src/NzbDrone.Core/Datastore/DbFactory.cs b/src/NzbDrone.Core/Datastore/DbFactory.cs index 01226bd2c..7f3476cf6 100644 --- a/src/NzbDrone.Core/Datastore/DbFactory.cs +++ b/src/NzbDrone.Core/Datastore/DbFactory.cs @@ -12,7 +12,8 @@ namespace NzbDrone.Core.Datastore { public interface IDbFactory { - IDatabase Create(MigrationType migrationType = MigrationType.Main, Action beforeMigration = null); + IDatabase Create(MigrationType migrationType = MigrationType.Main); + IDatabase Create(MigrationContext migrationContext); } public class DbFactory : IDbFactory @@ -43,12 +44,17 @@ namespace NzbDrone.Core.Datastore _connectionStringFactory = connectionStringFactory; } - public IDatabase Create(MigrationType migrationType = MigrationType.Main, Action beforeMigration = null) + public IDatabase Create(MigrationType migrationType = MigrationType.Main) + { + return Create(new MigrationContext(migrationType)); + } + + public IDatabase Create(MigrationContext migrationContext) { string connectionString; - switch (migrationType) + switch (migrationContext.MigrationType) { case MigrationType.Main: { @@ -66,9 +72,9 @@ namespace NzbDrone.Core.Datastore } } - _migrationController.MigrateToLatest(connectionString, migrationType, beforeMigration); + _migrationController.Migrate(connectionString, migrationContext); - var db = new Database(migrationType.ToString(), () => + var db = new Database(migrationContext.MigrationType.ToString(), () => { var dataMapper = new DataMapper(SQLiteFactory.Instance, connectionString) { diff --git a/src/NzbDrone.Core/Datastore/Migration/070_delay_profile.cs b/src/NzbDrone.Core/Datastore/Migration/070_delay_profile.cs index e0892cede..1c9c7e58b 100644 --- a/src/NzbDrone.Core/Datastore/Migration/070_delay_profile.cs +++ b/src/NzbDrone.Core/Datastore/Migration/070_delay_profile.cs @@ -74,9 +74,9 @@ namespace NzbDrone.Core.Datastore.Migration } } - private List GetProfiles(IDbConnection conn, IDbTransaction tran) + private List GetProfiles(IDbConnection conn, IDbTransaction tran) { - var profiles = new List(); + var profiles = new List(); using (IDbCommand getProfilesCmd = conn.CreateCommand()) { @@ -90,7 +90,7 @@ namespace NzbDrone.Core.Datastore.Migration var id = profileReader.GetInt32(0); var delay = profileReader.GetInt32(1); - profiles.Add(new Profile70 + profiles.Add(new Profile69 { Id = id, GrabDelay = delay * 60 @@ -145,21 +145,38 @@ namespace NzbDrone.Core.Datastore.Migration } } } - - getSeriesCmd.ExecuteNonQuery(); } } + } - private class Profile70 - { - public int Id { get; set; } - public int GrabDelay { get; set; } - } + public class Profile69 + { + public int Id { get; set; } + public int GrabDelay { get; set; } + } - private class Series70 - { - public int Id { get; set; } - public HashSet Tags { get; set; } - } + public class Series69 + { + public int Id { get; set; } + public List Tags { get; set; } + public DateTime? LastInfoSync { get; set; } + } + + public class Tag69 + { + public int Id { get; set; } + public string Label { get; set; } + } + + public class DelayProfile70 + { + public int Id { get; set; } + public bool EnableUsenet { get; set; } + public bool EnableTorrent { get; set; } + public int PreferredProtocol { get; set; } + public int UsenetDelay { get; set; } + public int TorrentDelay { get; set; } + public int Order { get; set; } + public List Tags { get; set; } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/071_unknown_quality_in_profile.cs b/src/NzbDrone.Core/Datastore/Migration/071_unknown_quality_in_profile.cs index e125ee729..a033e8410 100644 --- a/src/NzbDrone.Core/Datastore/Migration/071_unknown_quality_in_profile.cs +++ b/src/NzbDrone.Core/Datastore/Migration/071_unknown_quality_in_profile.cs @@ -19,72 +19,162 @@ namespace NzbDrone.Core.Datastore.Migration private void ConvertProfile(IDbConnection conn, IDbTransaction tran) { - var profiles = GetProfiles(conn, tran); + var updater = new ProfileUpdater70(conn, tran); + updater.PrependQuality(0); + updater.Commit(); + } + } + public class Profile70 + { + 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; } + } - foreach (var profile in profiles) - { - if (profile.Items.Any(p => p.Quality == 0)) continue; + public class ProfileItem70 + { + public int Quality { get; set; } + public bool Allowed { get; set; } + } - profile.Items.Insert(0, new ProfileItem71 - { - Quality = 0, - Allowed = false - }); + public class ProfileUpdater70 + { + private readonly IDbConnection _connection; + private readonly IDbTransaction _transaction; - var itemsJson = profile.Items.ToJson(); + private List _profiles; + private HashSet _changedProfiles = new HashSet(); - using (IDbCommand updateProfileCmd = conn.CreateCommand()) + public ProfileUpdater70(IDbConnection conn, IDbTransaction tran) + { + _connection = conn; + _transaction = tran; + + _profiles = GetProfiles(); + } + + public void Commit() + { + foreach (var profile in _changedProfiles) + { + using (var updateProfileCmd = _connection.CreateCommand()) { - updateProfileCmd.Transaction = tran; - updateProfileCmd.CommandText = "UPDATE Profiles SET Items = ? WHERE Id = ?"; - updateProfileCmd.AddParameter(itemsJson); + updateProfileCmd.Transaction = _transaction; + updateProfileCmd.CommandText = "UPDATE Profiles SET Name = ?, Cutoff = ?, Items = ?, Language = ? WHERE Id = ?"; + updateProfileCmd.AddParameter(profile.Name); + updateProfileCmd.AddParameter(profile.Cutoff); + updateProfileCmd.AddParameter(profile.Items.ToJson()); + updateProfileCmd.AddParameter(profile.Language); updateProfileCmd.AddParameter(profile.Id); updateProfileCmd.ExecuteNonQuery(); } } + + _changedProfiles.Clear(); } - private List GetProfiles(IDbConnection conn, IDbTransaction tran) + public void PrependQuality(int quality) { - var profiles = new List(); + foreach (var profile in _profiles) + { + if (profile.Items.Any(v => v.Quality == quality)) continue; + + profile.Items.Insert(0, new ProfileItem70 + { + Quality = quality, + Allowed = false + }); + + _changedProfiles.Add(profile); + } + } - using (IDbCommand getProfilesCmd = conn.CreateCommand()) + public void AppendQuality(int quality) + { + foreach (var profile in _profiles) { - getProfilesCmd.Transaction = tran; - getProfilesCmd.CommandText = @"SELECT Id, Items FROM Profiles"; + if (profile.Items.Any(v => v.Quality == quality)) continue; - using (IDataReader profileReader = getProfilesCmd.ExecuteReader()) + profile.Items.Add(new ProfileItem70 { - while (profileReader.Read()) - { - var id = profileReader.GetInt32(0); - var itemsJson = profileReader.GetString(1); + Quality = quality, + Allowed = false + }); - var items = Json.Deserialize>(itemsJson); - - profiles.Add(new Profile71 - { - Id = id, - Items = items - }); - } - } + _changedProfiles.Add(profile); } + } - return profiles; + 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 ProfileItem70 + { + Quality = quality, + Allowed = profile.Items[findIndex].Allowed + }); + + if (profile.Cutoff == find) + { + profile.Cutoff = quality; + } + + _changedProfiles.Add(profile); + } } - private class Profile71 + public void SplitQualityAppend(int find, int quality) { - public int Id { get; set; } - public List Items { get; set; } + 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 ProfileItem70 + { + Quality = quality, + Allowed = false + }); + + _changedProfiles.Add(profile); + } } - private class ProfileItem71 + private List GetProfiles() { - public int Quality { get; set; } - public bool Allowed { get; set; } + 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 Profile70 + { + Id = profileReader.GetInt32(0), + Name = profileReader.GetString(1), + Cutoff = profileReader.GetInt32(2), + Items = Json.Deserialize>(profileReader.GetString(3)), + Language = profileReader.GetInt32(4) + }); + } + } + } + + return profiles; } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/072_history_grabid.cs b/src/NzbDrone.Core/Datastore/Migration/072_history_grabid.cs index a296fd219..eb3b8a239 100644 --- a/src/NzbDrone.Core/Datastore/Migration/072_history_grabid.cs +++ b/src/NzbDrone.Core/Datastore/Migration/072_history_grabid.cs @@ -52,7 +52,7 @@ namespace NzbDrone.Core.Datastore.Migration using (var updateHistoryCmd = conn.CreateCommand()) { updateHistoryCmd.Transaction = tran; - updateHistoryCmd.CommandText = @"UPDATE History SET DownloadId = ? , Data = ? WHERE Id = ?"; + updateHistoryCmd.CommandText = @"UPDATE History SET DownloadId = ?, Data = ? WHERE Id = ?"; updateHistoryCmd.AddParameter(downloadId); updateHistoryCmd.AddParameter(dic.ToJson()); @@ -63,4 +63,17 @@ namespace NzbDrone.Core.Datastore.Migration } } } + + public class History72 + { + public int EpisodeId { get; set; } + public int SeriesId { get; set; } + public string SourceTitle { get; set; } + public string Quality { get; set; } + public DateTime Date { get; set; } + public int EventType { get; set; } + public Dictionary Data { get; set; } + + public string DownloadId { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/075_force_lib_update.cs b/src/NzbDrone.Core/Datastore/Migration/075_force_lib_update.cs index f9f3d30af..5a9336f64 100644 --- a/src/NzbDrone.Core/Datastore/Migration/075_force_lib_update.cs +++ b/src/NzbDrone.Core/Datastore/Migration/075_force_lib_update.cs @@ -1,4 +1,5 @@ -using FluentMigrator; +using System; +using FluentMigrator; using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration @@ -18,5 +19,11 @@ namespace NzbDrone.Core.Datastore.Migration } } - + public class ScheduledTasks75 + { + public int Id { get; set; } + public string TypeName { get; set; } + public int Interval { get; set; } + public DateTime LastExecution { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/081_move_dot_prefix_to_transmission_category.cs b/src/NzbDrone.Core/Datastore/Migration/081_move_dot_prefix_to_transmission_category.cs index a29376dc4..80fd3ba06 100644 --- a/src/NzbDrone.Core/Datastore/Migration/081_move_dot_prefix_to_transmission_category.cs +++ b/src/NzbDrone.Core/Datastore/Migration/081_move_dot_prefix_to_transmission_category.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using FluentMigrator; +using Newtonsoft.Json.Linq; using NzbDrone.Common.Extensions; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration.Framework; @@ -53,4 +54,41 @@ namespace NzbDrone.Core.Datastore.Migration } } } + + public class DownloadClientDefinition81 + { + public int Id { get; set; } + public bool Enable { get; set; } + public string Name { get; set; } + public string Implementation { get; set; } + public JObject Settings { get; set; } + public string ConfigContract { get; set; } + } + + public class SabnzbdSettings81 + { + public string Host { get; set; } + public int Port { get; set; } + public string ApiKey { get; set; } + public string Username { get; set; } + public string Password { get; set; } + public string TvCategory { get; set; } + public int RecentTvPriority { get; set; } + public int OlderTvPriority { get; set; } + public bool UseSsl { get; set; } + } + + public class TransmissionSettings81 + { + public string Host { get; set; } + public int Port { get; set; } + public string UrlBase { get; set; } + public string Username { get; set; } + public string Password { get; set; } + public string TvCategory { get; set; } + public string TvDirectory { get; set; } + public int RecentTvPriority { get; set; } + public int OlderTvPriority { get; set; } + public bool UseSsl { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/084_update_quality_minmax_size.cs b/src/NzbDrone.Core/Datastore/Migration/084_update_quality_minmax_size.cs index 6e9b68dfd..9cf2cd8dd 100644 --- a/src/NzbDrone.Core/Datastore/Migration/084_update_quality_minmax_size.cs +++ b/src/NzbDrone.Core/Datastore/Migration/084_update_quality_minmax_size.cs @@ -15,4 +15,13 @@ namespace NzbDrone.Core.Datastore.Migration Execute.Sql("UPDATE QualityDefinitions SET MaxSize = NULL WHERE Quality = 10 OR MaxSize = 0"); } } + + public class QualityDefinition84 + { + public int Id { get; set; } + public int Quality { get; set; } + public string Title { get; set; } + public int? MinSize { get; set; } + public int? MaxSize { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/085_expand_transmission_urlbase.cs b/src/NzbDrone.Core/Datastore/Migration/085_expand_transmission_urlbase.cs index 56df0f514..81e6267bc 100644 --- a/src/NzbDrone.Core/Datastore/Migration/085_expand_transmission_urlbase.cs +++ b/src/NzbDrone.Core/Datastore/Migration/085_expand_transmission_urlbase.cs @@ -58,4 +58,16 @@ namespace NzbDrone.Core.Datastore.Migration } } } + + public class DelugeSettings85 + { + public string Host { get; set; } + public int Port { get; set; } + public string UrlBase { get; set; } + public string Password { get; set; } + public string TvCategory { get; set; } + public int RecentTvPriority { get; set; } + public int OlderTvPriority { get; set; } + public bool UseSsl { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/086_pushbullet_device_ids.cs b/src/NzbDrone.Core/Datastore/Migration/086_pushbullet_device_ids.cs index 9e89a0513..432a13ff3 100644 --- a/src/NzbDrone.Core/Datastore/Migration/086_pushbullet_device_ids.cs +++ b/src/NzbDrone.Core/Datastore/Migration/086_pushbullet_device_ids.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Data; using FluentMigrator; +using Newtonsoft.Json.Linq; using NzbDrone.Common.Extensions; using NzbDrone.Common.Serializer; using NzbDrone.Core.Datastore.Migration.Framework; @@ -34,7 +35,7 @@ namespace NzbDrone.Core.Datastore.Migration { var deviceId = settings.GetValueOrDefault("deviceId", "") as string; - settings.Add("deviceIds", deviceId); + settings.Add("deviceIds", new[] { deviceId }); settings.Remove("deviceId"); using (var updateCmd = conn.CreateCommand()) @@ -52,4 +53,25 @@ namespace NzbDrone.Core.Datastore.Migration } } } + + public class Notification86 + { + public int Id { get; set; } + public string Name { get; set; } + public int OnGrab { get; set; } + public int OnDownload { get; set; } + public JObject Settings { get; set; } + public string Implementation { get; set; } + public string ConfigContract { get; set; } + public int OnUpgrade { get; set; } + public List Tags { get; set; } + } + + public class PushBulletSettings86 + { + public string ApiKey { get; set; } + public string[] DeviceIds { get; set; } + public string ChannelTags { get; set; } + public string SenderId { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/088_pushbullet_devices_channels_list.cs b/src/NzbDrone.Core/Datastore/Migration/088_pushbullet_devices_channels_list.cs index 052bb4def..b219dfd59 100644 --- a/src/NzbDrone.Core/Datastore/Migration/088_pushbullet_devices_channels_list.cs +++ b/src/NzbDrone.Core/Datastore/Migration/088_pushbullet_devices_channels_list.cs @@ -69,4 +69,12 @@ namespace NzbDrone.Core.Datastore.Migration } } } + + public class PushBulletSettings88 + { + public string ApiKey { get; set; } + public string[] DeviceIds { get; set; } + public string[] ChannelTags { get; set; } + public string SenderId { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/090_update_kickass_url.cs b/src/NzbDrone.Core/Datastore/Migration/090_update_kickass_url.cs index aa8166803..ec96f48dc 100644 --- a/src/NzbDrone.Core/Datastore/Migration/090_update_kickass_url.cs +++ b/src/NzbDrone.Core/Datastore/Migration/090_update_kickass_url.cs @@ -1,4 +1,5 @@ using FluentMigrator; +using Newtonsoft.Json.Linq; using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration @@ -15,4 +16,21 @@ namespace NzbDrone.Core.Datastore.Migration ); } } + + public class IndexerDefinition90 + { + public int Id { get; set; } + public string Name { get; set; } + public JObject Settings { get; set; } + public string Implementation { get; set; } + public string ConfigContract { get; set; } + public bool EnableRss { get; set; } + public bool EnableSearch { get; set; } + } + + public class KickassTorrentsSettings90 + { + public string BaseUrl { get; set; } + public bool VerifiedOnly { get; set; } + } } diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs index 0d49450af..c8882aab0 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs @@ -5,14 +5,14 @@ namespace NzbDrone.Core.Datastore.Migration.Framework public class MigrationContext { public MigrationType MigrationType { get; private set; } + public long? DesiredVersion { get; set; } - public Action BeforeMigration { get; private set; } + public Action BeforeMigration { get; set; } - public MigrationContext(MigrationType migrationType, Action beforeAction) + public MigrationContext(MigrationType migrationType, long? desiredVersion = null) { MigrationType = migrationType; - - BeforeMigration = beforeAction; + DesiredVersion = desiredVersion; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs index a505078fe..f7ef7a896 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework { public interface IMigrationController { - void MigrateToLatest(string connectionString, MigrationType migrationType, Action beforeMigration); + void Migrate(string connectionString, MigrationContext migrationContext); } public class MigrationController : IMigrationController @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework _announcer = announcer; } - public void MigrateToLatest(string connectionString, MigrationType migrationType, Action beforeMigration) + public void Migrate(string connectionString, MigrationContext migrationContext) { var sw = Stopwatch.StartNew(); @@ -28,17 +28,25 @@ namespace NzbDrone.Core.Datastore.Migration.Framework var assembly = Assembly.GetExecutingAssembly(); - var migrationContext = new RunnerContext(_announcer) - { - Namespace = "NzbDrone.Core.Datastore.Migration", - ApplicationContext = new MigrationContext(migrationType, beforeMigration) - }; + var runnerContext = new RunnerContext(_announcer) + { + Namespace = "NzbDrone.Core.Datastore.Migration", + ApplicationContext = migrationContext + }; var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 }; var factory = new NzbDroneSqliteProcessorFactory(); var processor = factory.Create(connectionString, _announcer, options); - var runner = new MigrationRunner(assembly, migrationContext, processor); - runner.MigrateUp(true); + var runner = new MigrationRunner(assembly, runnerContext, processor); + + if (migrationContext.DesiredVersion.HasValue) + { + runner.MigrateUp(migrationContext.DesiredVersion.Value, true); + } + else + { + runner.MigrateUp(true); + } sw.Stop();