From cb8cb1691f3234ca09d36ca7906efdaef4bb0000 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Wed, 15 Jun 2011 23:33:01 -0700 Subject: [PATCH] SeriesProvider is now Subsonic free. --- NzbDrone.Core.Test/EpisodeProviderTest.cs | 147 ++++++++++-------- NzbDrone.Core.Test/SeriesProviderTest.cs | Bin 6648 -> 6589 bytes NzbDrone.Core.Test/dbBenchmark.cs | 5 +- NzbDrone.Core/CentralDispatch.cs | 37 +---- NzbDrone.Core/Datastore/CustomeMapper.cs | 17 +- .../Datastore/Migrations/MigrationExport.cs | 19 +++ .../PetaPoco}/PetaPoco.cs | 14 +- NzbDrone.Core/NzbDrone.Core.csproj | 5 +- NzbDrone.Core/Providers/EpisodeProvider.cs | 88 +++++++---- NzbDrone.Core/Repository/Episode.cs | 3 +- 10 files changed, 195 insertions(+), 140 deletions(-) rename NzbDrone.Core/{Models => Datastore/PetaPoco}/PetaPoco.cs (99%) diff --git a/NzbDrone.Core.Test/EpisodeProviderTest.cs b/NzbDrone.Core.Test/EpisodeProviderTest.cs index abd537fca..2cbc2bb00 100644 --- a/NzbDrone.Core.Test/EpisodeProviderTest.cs +++ b/NzbDrone.Core.Test/EpisodeProviderTest.cs @@ -13,6 +13,7 @@ using NzbDrone.Core.Providers; using NzbDrone.Core.Repository; using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; +using PetaPoco; using SubSonic.Repository; using TvdbLib.Data; @@ -22,6 +23,29 @@ namespace NzbDrone.Core.Test // ReSharper disable InconsistentNaming public class EpisodeProviderTest : TestBase { + + [Test] + public void GetEpisodesBySeason_success() + { + var episodes = Builder.CreateListOfSize(10) + .WhereAll().Have(c => c.SeriesId = 12) + .WhereTheFirst(5).Have(c => c.SeasonNumber = 1) + .AndTheRemaining().Have(c => c.SeasonNumber = 2).Build(); + + var db = MockLib.GetEmptyDatabase(); + var mocker = new AutoMoqer(); + mocker.SetConstant(db); + + episodes.ToList().ForEach(c => db.Insert(c)); + + //Act + var seasonEposodes = mocker.Resolve().GetEpisodesBySeason(12, 2); + + //Assert + db.Fetch().Should().HaveCount(10); + seasonEposodes.Should().HaveCount(5); + } + [Test] public void RefreshEpisodeInfo_emptyRepo() { @@ -42,7 +66,7 @@ namespace NzbDrone.Core.Test var mocker = new AutoMoqer(); - mocker.SetConstant(MockLib.GetEmptyRepository()); + mocker.SetConstant(MockLib.GetEmptyDatabase()); mocker.GetMock() .Setup(c => c.GetSeries(seriesId, true)) @@ -61,65 +85,72 @@ namespace NzbDrone.Core.Test [Test] - public void new_episodes_only_calls_AddMany() + public void new_episodes_only_calls_Insert() { const int seriesId = 71663; - var fakeEpisodes = Builder.CreateNew() + var tvdbSeries = Builder.CreateNew() .With(c => c.Episodes = new List(Builder.CreateListOfSize(5).Build()) ).With(c => c.Id = seriesId).Build(); var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); + var currentEpisodes = new List(); + var mocker = new AutoMoqer(); mocker.GetMock(MockBehavior.Strict) .Setup(c => c.GetSeries(seriesId, true)) - .Returns(fakeEpisodes); + .Returns(tvdbSeries); + + mocker.GetMock() + .Setup(d => d.Fetch(It.IsAny(), It.IsAny())) + .Returns(currentEpisodes); //Act mocker.Resolve().RefreshEpisodeInfo(fakeSeries); //Assert - mocker.GetMock().Verify( - c => c.AddMany(It.Is>(e => e.Count() == fakeEpisodes.Episodes.Count)), Times.Once()); - mocker.GetMock().Verify(c => c.UpdateMany(It.Is>(e => e.Count() == 0)), - Times.AtMostOnce()); + mocker.GetMock().Verify(c => c.Insert(It.IsAny()), Times.Exactly(tvdbSeries.Episodes.Count)); + mocker.GetMock().Verify(c => c.Update(It.IsAny()), Times.Never()); + mocker.VerifyAllMocks(); } [Test] - public void existing_episodes_only_calls_UpdateMany() + public void existing_episodes_only_calls_Update() { const int seriesId = 71663; - var fakeEpisodes = Builder.CreateNew() + var tvdbSeries = Builder.CreateNew() .With(c => c.Episodes = new List(Builder.CreateListOfSize(5).Build()) ).With(c => c.Id = seriesId).Build(); var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); + var currentEpisodes = new List(); + foreach (var tvDbEpisode in tvdbSeries.Episodes) + { + currentEpisodes.Add(new Episode { TvDbEpisodeId = tvDbEpisode.Id }); + } var mocker = new AutoMoqer(); mocker.GetMock(MockBehavior.Strict) .Setup(c => c.GetSeries(seriesId, true)) - .Returns(fakeEpisodes); + .Returns(tvdbSeries); - mocker.GetMock() - .Setup(c => c.Single(It.IsAny>>())) - .Returns(Builder.CreateNew().Build); + mocker.GetMock() + .Setup(d => d.Fetch(It.IsAny(), It.IsAny())) + .Returns(currentEpisodes); //Act mocker.Resolve().RefreshEpisodeInfo(fakeSeries); //Assert - mocker.GetMock().Verify(c => c.AddMany(It.Is>(e => e.Count() == 0)), - Times.AtMostOnce()); - mocker.GetMock().Verify( - c => c.UpdateMany(It.Is>(e => e.Count() == fakeEpisodes.Episodes.Count)), - Times.Once()); + mocker.GetMock().Verify(c => c.Insert(It.IsAny()), Times.Never()); + mocker.GetMock().Verify(c => c.Update(It.IsAny()), Times.Exactly(tvdbSeries.Episodes.Count)); mocker.VerifyAllMocks(); } @@ -128,7 +159,7 @@ namespace NzbDrone.Core.Test public void should_try_to_get_existing_episode_using_tvdbid_first() { const int seriesId = 71663; - var fakeEpisodes = Builder.CreateNew() + var fakeTvDbResult = Builder.CreateNew() .With(c => c.Id = seriesId) .With(c => c.Episodes = new List( Builder.CreateListOfSize(1) @@ -137,33 +168,31 @@ namespace NzbDrone.Core.Test ) .Build(); + var fakeEpisodeList = new List { new Episode { TvDbEpisodeId = 99, SeasonNumber = 10, EpisodeNumber = 10 } }; var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); - var mocker = new AutoMoqer(); + mocker.GetMock() + .Setup(d => d.Fetch(It.IsAny(), It.IsAny())) + .Returns(fakeEpisodeList); - var repo = MockLib.GetEmptyRepository(); - repo.Add( - Builder.CreateNew().With(c => c.TvDbEpisodeId = fakeEpisodes.Episodes[0].Id).Build()); - mocker.SetConstant(repo); - - mocker.GetMock(MockBehavior.Strict) + mocker.GetMock() .Setup(c => c.GetSeries(seriesId, true)) - .Returns(fakeEpisodes); + .Returns(fakeTvDbResult); //Act mocker.Resolve().RefreshEpisodeInfo(fakeSeries); //Assert mocker.VerifyAllMocks(); - repo.All().Should().HaveCount(1); + mocker.GetMock().Verify(c => c.Update(fakeEpisodeList[0]), Times.Once()); } [Test] public void should_try_to_get_existing_episode_using_tvdbid_first_then_season_episode() { const int seriesId = 71663; - var fakeEpisodes = Builder.CreateNew() + var tvdbSeries = Builder.CreateNew() .With(c => c.Id = seriesId) .With(c => c.Episodes = new List{ Builder.CreateNew() @@ -187,20 +216,20 @@ namespace NzbDrone.Core.Test var mocker = new AutoMoqer(); - var repo = MockLib.GetEmptyRepository(); - repo.Add(localEpisode); - mocker.SetConstant(repo); - mocker.GetMock(MockBehavior.Strict) .Setup(c => c.GetSeries(seriesId, true)) - .Returns(fakeEpisodes); + .Returns(tvdbSeries); + + mocker.GetMock() + .Setup(d => d.Fetch(It.IsAny(), It.IsAny())) + .Returns(new List { localEpisode }); //Act mocker.Resolve().RefreshEpisodeInfo(fakeSeries); //Assert mocker.VerifyAllMocks(); - repo.All().Should().HaveCount(1); + mocker.GetMock().Verify(c => c.Update(localEpisode), Times.Once()); } @@ -208,51 +237,43 @@ namespace NzbDrone.Core.Test public void existing_episodes_keep_their_episodeId_file_id() { const int seriesId = 71663; - var faketvDbResponse = Builder.CreateNew() + var tvdbSeries = Builder.CreateNew() .With(c => c.Episodes = new List(Builder.CreateListOfSize(5).Build()) ).With(c => c.Id = seriesId).Build(); var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); - var fakeEpisode = - Builder.CreateNew().With(c => c.EpisodeFileId = 69).And(c => c.EpisodeId = 99).Build(); + + var currentEpisodes = new List(); + foreach (var tvDbEpisode in tvdbSeries.Episodes) + { + currentEpisodes.Add(new Episode { TvDbEpisodeId = tvDbEpisode.Id, EpisodeId = 99, EpisodeFileId = 69, Ignored = true }); + } var mocker = new AutoMoqer(); mocker.GetMock(MockBehavior.Strict) .Setup(c => c.GetSeries(seriesId, true)) - .Returns(faketvDbResponse); + .Returns(tvdbSeries); - IEnumerable updatedEpisodes = null; + var updatedEpisodes = new List(); - mocker.GetMock() - .Setup(c => c.Single(It.IsAny>>())) - .Returns(fakeEpisode); + mocker.GetMock() + .Setup(d => d.Fetch(It.IsAny(), It.IsAny())) + .Returns(currentEpisodes); - mocker.GetMock() - .Setup(c => c.UpdateMany(It.IsAny>())) - .Returns(faketvDbResponse.Episodes.Count) - .Callback>(r => updatedEpisodes = r); + mocker.GetMock() + .Setup(c => c.Update(It.IsAny())) + .Returns(1) + .Callback(ep => updatedEpisodes.Add(ep)); //Act mocker.Resolve().RefreshEpisodeInfo(fakeSeries); //Assert - mocker.GetMock().Verify(c => c.AddMany(It.Is>(e => e.Count() == 0)), - Times.AtMostOnce()); - mocker.GetMock().Verify( - c => c.UpdateMany(It.Is>(e => e.Count() == faketvDbResponse.Episodes.Count)), - Times.Once()); - mocker.GetMock().Verify( - c => - c.UpdateMany( - It.Is>( - e => e.Where(g => g.EpisodeFileId == 69).Count() == faketvDbResponse.Episodes.Count)), - Times.Once()); - - - updatedEpisodes.Should().HaveSameCount(faketvDbResponse.Episodes); + updatedEpisodes.Should().HaveSameCount(tvdbSeries.Episodes); updatedEpisodes.Should().OnlyContain(c => c.EpisodeId == 99); updatedEpisodes.Should().OnlyContain(c => c.EpisodeFileId == 69); + updatedEpisodes.Should().OnlyContain(c => c.Ignored == true); } @@ -347,7 +368,7 @@ namespace NzbDrone.Core.Test public void Add_daily_show_episodes() { var mocker = new AutoMoqer(); - mocker.SetConstant(MockLib.GetEmptyRepository()); + mocker.SetConstant(MockLib.GetEmptyDatabase()); mocker.Resolve(); const int tvDbSeriesId = 71256; //act diff --git a/NzbDrone.Core.Test/SeriesProviderTest.cs b/NzbDrone.Core.Test/SeriesProviderTest.cs index d8f4a283a58e6138ed1208a421791ffb08e2f20b..f9c77840ab9098f055c0a05de0461d5db5be72e7 100644 GIT binary patch delta 106 zcmexiyw`Yx3diIc7TL+Z9I=yGMMNjB7vPz^Q%GQPzW~={MShXZf}B%1*~$`&6jG8V v*9h3lrX*=v^K$WWDIkHABt6f(;?$y&%^bqqj9fsaQ2t~N;mpl*MWR^&aO)kh delta 157 zcmdmM{KI&I3diKNygZZFv&v3(().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InTransientScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().To().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); - + _kernel.Bind().ToMethod(c => Connection.GetPetaPocoDb(Connection.MainConnectionString)).InRequestScope(); _kernel.Bind().ToConstant(Connection.CreateSimpleRepository(Connection.MainConnectionString)).InSingletonScope(); - _kernel.Bind().ToConstant(Connection.GetPetaPocoDb(Connection.MainConnectionString)).InRequestScope(); _kernel.Bind().ToConstant(Connection.CreateSimpleRepository(Connection.LogConnectionString)).WhenInjectedInto().InSingletonScope(); _kernel.Bind().ToConstant(Connection.CreateSimpleRepository(Connection.LogConnectionString)).WhenInjectedInto().InSingletonScope(); } @@ -104,10 +77,10 @@ namespace NzbDrone.Core private static void BindIndexers() { - _kernel.Bind().To().InSingletonScope(); - _kernel.Bind().To().InSingletonScope(); - _kernel.Bind().To().InSingletonScope(); - _kernel.Bind().To().InSingletonScope(); + _kernel.Bind().To().InTransientScope(); + _kernel.Bind().To().InTransientScope(); + _kernel.Bind().To().InTransientScope(); + _kernel.Bind().To().InTransientScope(); var indexers = _kernel.GetAll(); _kernel.Get().InitializeIndexers(indexers.ToList()); diff --git a/NzbDrone.Core/Datastore/CustomeMapper.cs b/NzbDrone.Core/Datastore/CustomeMapper.cs index cb993927a..4e3362aaa 100644 --- a/NzbDrone.Core/Datastore/CustomeMapper.cs +++ b/NzbDrone.Core/Datastore/CustomeMapper.cs @@ -11,7 +11,8 @@ namespace NzbDrone.Core.Datastore if ((SourceType == typeof(Int32) || SourceType == typeof(Int64)) && destinationInfo.Type.IsGenericType && destinationInfo.Type.GetGenericTypeDefinition() == typeof(Nullable<>)) { // If it is NULLABLE, then get the underlying type. eg if "Nullable" then this will return just "int" - if (destinationInfo.Type.GetGenericArguments()[0].IsEnum) + Type genericArgument = destinationInfo.Type.GetGenericArguments()[0]; + if (genericArgument == typeof(DayOfWeek)) { return delegate(object s) { @@ -25,6 +26,20 @@ namespace NzbDrone.Core.Datastore return (Nullable)value; }; } + else + { + return delegate(object s) + { + int value; + Int32.TryParse(s.ToString(), out value); + if (value == 0) + { + return null; + } + + return value; + }; + } } return base.GetFromDbConverter(destinationInfo, SourceType); diff --git a/NzbDrone.Core/Datastore/Migrations/MigrationExport.cs b/NzbDrone.Core/Datastore/Migrations/MigrationExport.cs index 74fef9048..524415601 100644 --- a/NzbDrone.Core/Datastore/Migrations/MigrationExport.cs +++ b/NzbDrone.Core/Datastore/Migrations/MigrationExport.cs @@ -27,6 +27,25 @@ namespace NzbDrone.Core.Datastore.Migrations .WithNotNullableColumn("SeasonFolder", DbType.Boolean) .WithNullableColumn("LastInfoSync", DbType.DateTime) .WithNullableColumn("LastDiskSync", DbType.DateTime); + + + db.CreateTable("Episodes") + .WithPrimaryKeyColumn("EpisodeId", DbType.Int32).AsIdentity() + .WithNullableColumn("TvDbEpisodeId", DbType.Int32) + + .WithNotNullableColumn("SeriesId", DbType.Int32) + .WithNotNullableColumn("SeasonNumber", DbType.Int16) + .WithNotNullableColumn("EpisodeNumber", DbType.Int16) + .WithNotNullableColumn("Title", DbType.String).HavingDefault(String.Empty) + + .WithNotNullableColumn("Overview", DbType.String).HavingDefault(String.Empty) + .WithNotNullableColumn("Ignored", DbType.Boolean).HavingDefault(false) + .WithNullableColumn("EpisodeFileId", DbType.Int32) + .WithNullableColumn("AirDate", DbType.DateTime) + .WithNullableColumn("GrabDate", DbType.DateTime); + + + } } } diff --git a/NzbDrone.Core/Models/PetaPoco.cs b/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs similarity index 99% rename from NzbDrone.Core/Models/PetaPoco.cs rename to NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs index 24555a31c..8abc47cc4 100644 --- a/NzbDrone.Core/Models/PetaPoco.cs +++ b/NzbDrone.Core/Datastore/PetaPoco/PetaPoco.cs @@ -26,7 +26,6 @@ using System.Linq.Expressions; // ReSharper disable namespace PetaPoco - { // Poco's marked [Explicit] require all column properties to be marked [AttributeUsage(AttributeTargets.Class)] @@ -354,12 +353,16 @@ namespace PetaPoco { _sharedConnection = _factory.CreateConnection(); _sharedConnection.ConnectionString = _connectionString; - _sharedConnection.Open(); if (KeepConnectionAlive) _sharedConnectionDepth++; // Make sure you call Dispose } + + if (_sharedConnection.State != ConnectionState.Open) + _sharedConnection.Open(); + _sharedConnectionDepth++; + } // Close a previously opened connection @@ -860,9 +863,6 @@ namespace PetaPoco var pd = PocoData.ForType(typeof(T)); try { - if (_sharedConnection.State != ConnectionState.Open) - _sharedConnection.Open(); - r = cmd.ExecuteReader(); OnExecutedCommand(cmd); } @@ -1297,9 +1297,7 @@ namespace PetaPoco { using (var cmd = CreateCommand(_sharedConnection, "")) { - if(_sharedConnection.State != ConnectionState.Open) - _sharedConnection.Open(); - + var pd = PocoData.ForObject(poco, primaryKeyName); var names = new List(); var values = new List(); diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 7a2918f5d..508f85abe 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -185,7 +185,7 @@ - + @@ -306,6 +306,9 @@ + + +