mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-14 11:23:42 +02:00
less intrusive cache prevention.
more tests.
This commit is contained in:
parent
5dbaaee005
commit
9f829c1442
@ -1,12 +1,8 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using Db4objects.Db4o.Linq;
|
||||
|
||||
@ -18,7 +14,7 @@ public class ObjectDatabaseFixture : CoreTest
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
WithObjectDb();
|
||||
WithObjectDb(false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -27,7 +23,7 @@ public void should_be_able_to_write_to_database()
|
||||
|
||||
var series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
ObjDb.Save(series);
|
||||
ObjDb.Create(series);
|
||||
|
||||
ObjDb.Ext().Purge();
|
||||
|
||||
@ -41,14 +37,76 @@ public void should_not_store_dirty_data_in_cache()
|
||||
var episode = Builder<Episode>.CreateNew().Build();
|
||||
|
||||
//Save series without episode attached
|
||||
ObjDb.Save(episode);
|
||||
ObjDb.Create(episode);
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Single().Series.Should().BeNull();
|
||||
|
||||
episode.Series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Single().Series.Should().BeNull();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void rollback_should_reset_state()
|
||||
{
|
||||
var episode = Builder<Episode>.CreateNew().Build();
|
||||
|
||||
ObjDb.Create(episode);
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Should().HaveCount(1);
|
||||
|
||||
ObjDb.Rollback();
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Should().HaveCount(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void roolback_should_only_roll_back_what_is_not_commited()
|
||||
{
|
||||
var episode = Builder<Episode>.CreateNew().Build();
|
||||
var series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
ObjDb.Create(episode);
|
||||
|
||||
ObjDb.Commit();
|
||||
|
||||
ObjDb.Create(series);
|
||||
|
||||
ObjDb.Rollback();
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Should().HaveCount(1);
|
||||
ObjDb.AsQueryable<Series>().Should().HaveCount(0);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_store_nested_objects()
|
||||
{
|
||||
var episode = Builder<Episode>.CreateNew().Build();
|
||||
episode.Series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
ObjDb.Create(episode);
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Should().HaveCount(1);
|
||||
ObjDb.AsQueryable<Episode>().Single().Series.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_update_nested_objects()
|
||||
{
|
||||
var episode = Builder<Episode>.CreateNew().Build();
|
||||
episode.Series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
ObjDb.Create(episode);
|
||||
|
||||
episode.Series.Title = "UpdatedTitle";
|
||||
|
||||
ObjDb.Update(episode,2);
|
||||
|
||||
ObjDb.AsQueryable<Episode>().Should().HaveCount(1);
|
||||
ObjDb.AsQueryable<Episode>().Single().Series.Should().NotBeNull();
|
||||
ObjDb.AsQueryable<Episode>().Single().Series.Title.Should().Be("UpdatedTitle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,9 +93,17 @@ protected void WithRealDb()
|
||||
Mocker.SetConstant(Db);
|
||||
}
|
||||
|
||||
protected void WithObjectDb()
|
||||
protected void WithObjectDb(bool memory = true)
|
||||
{
|
||||
_objDb = new ObjectDbSessionFactory().Create(new PagingMemoryStorage());
|
||||
if (memory)
|
||||
{
|
||||
_objDb = new ObjectDbSessionFactory().Create(new PagingMemoryStorage());
|
||||
}
|
||||
else
|
||||
{
|
||||
_objDb = new ObjectDbSessionFactory().Create(dbName: Guid.NewGuid().ToString());
|
||||
}
|
||||
|
||||
Mocker.SetConstant(ObjDb);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlServerCe;
|
||||
using Db4objects.Db4o;
|
||||
using Db4objects.Db4o.IO;
|
||||
using Db4objects.Db4o.Internal;
|
||||
using Db4objects.Db4o.Internal.Config;
|
||||
using StackExchange.Profiling;
|
||||
using StackExchange.Profiling.Data;
|
||||
@ -27,23 +24,4 @@ public override DbConnection CreateConnection()
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ObjectDbSessionFactory
|
||||
{
|
||||
public IObjectDbSession Create(IStorage storage = null)
|
||||
{
|
||||
if (storage == null)
|
||||
{
|
||||
storage = new FileStorage();
|
||||
}
|
||||
|
||||
var config = Db4oEmbedded.NewConfiguration();
|
||||
config.File.Storage = storage;
|
||||
|
||||
|
||||
var objectContainer = Db4oEmbedded.OpenFile(config, "nzbdrone.db4o");
|
||||
return new ObjectDbSession((ObjectContainerBase)objectContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
NzbDrone.Core/Datastore/NoCacheReferenceSystem.cs
Normal file
15
NzbDrone.Core/Datastore/NoCacheReferenceSystem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Linq;
|
||||
using Db4objects.Db4o.Internal;
|
||||
using Db4objects.Db4o.Internal.References;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public class NoCacheReferenceSystem : HashcodeReferenceSystem
|
||||
{
|
||||
public override ObjectReference ReferenceForId(int id)
|
||||
{
|
||||
//never return an in memory instance of objects as query result. always go to db.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
using System.Linq;
|
||||
using Db4objects.Db4o;
|
||||
using Db4objects.Db4o.Foundation;
|
||||
using Db4objects.Db4o.Internal;
|
||||
using Db4objects.Db4o.Internal.References;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public class NoCahceRefrenceSystem : IReferenceSystem
|
||||
{
|
||||
private ObjectReference _hashCodeTree;
|
||||
private ObjectReference _idTree;
|
||||
|
||||
internal NoCahceRefrenceSystem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void AddNewReference(ObjectReference @ref)
|
||||
{
|
||||
AddReference(@ref);
|
||||
}
|
||||
|
||||
public virtual void AddExistingReference(ObjectReference @ref)
|
||||
{
|
||||
AddReference(@ref);
|
||||
}
|
||||
|
||||
public virtual void Commit()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public virtual ObjectReference ReferenceForId(int id)
|
||||
{
|
||||
if (DTrace.enabled)
|
||||
DTrace.GetYapobject.Log(id);
|
||||
if (_idTree == null)
|
||||
return null;
|
||||
if (!ObjectReference.IsValidId(id))
|
||||
return null;
|
||||
else
|
||||
return _idTree.Id_find(id);
|
||||
}
|
||||
|
||||
public virtual ObjectReference ReferenceForObject(object obj)
|
||||
{
|
||||
if (_hashCodeTree == null)
|
||||
return null;
|
||||
else
|
||||
return _hashCodeTree.Hc_find(obj);
|
||||
}
|
||||
|
||||
public virtual void RemoveReference(ObjectReference @ref)
|
||||
{
|
||||
if (DTrace.enabled)
|
||||
DTrace.ReferenceRemoved.Log(@ref.GetID());
|
||||
if (_hashCodeTree != null)
|
||||
_hashCodeTree = _hashCodeTree.Hc_remove(@ref);
|
||||
if (_idTree == null)
|
||||
return;
|
||||
_idTree = _idTree.Id_remove(@ref);
|
||||
}
|
||||
|
||||
public virtual void Rollback()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void TraverseReferences(IVisitor4 visitor)
|
||||
{
|
||||
if (_hashCodeTree == null)
|
||||
return;
|
||||
_hashCodeTree.Hc_traverse(visitor);
|
||||
}
|
||||
|
||||
public virtual void Discarded()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_hashCodeTree = null;
|
||||
_idTree = null;
|
||||
}
|
||||
|
||||
private void AddReference(ObjectReference @ref)
|
||||
{
|
||||
@ref.Ref_init();
|
||||
IdAdd(@ref);
|
||||
HashCodeAdd(@ref);
|
||||
}
|
||||
|
||||
private void HashCodeAdd(ObjectReference @ref)
|
||||
{
|
||||
if (_hashCodeTree == null)
|
||||
_hashCodeTree = @ref;
|
||||
else
|
||||
_hashCodeTree = _hashCodeTree.Hc_add(@ref);
|
||||
}
|
||||
|
||||
private void IdAdd(ObjectReference @ref)
|
||||
{
|
||||
if (DTrace.enabled)
|
||||
DTrace.IdTreeAdd.Log(@ref.GetID());
|
||||
if (_idTree == null)
|
||||
_idTree = @ref;
|
||||
else
|
||||
_idTree = _idTree.Id_add(@ref);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,14 +4,13 @@
|
||||
using System.Linq;
|
||||
using Db4objects.Db4o;
|
||||
using Db4objects.Db4o.Internal;
|
||||
using Db4objects.Db4o.Internal.References;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public interface IObjectDbSession : IObjectContainer
|
||||
{
|
||||
void Save(object obj);
|
||||
void Save(object obj, int depth);
|
||||
void Create(object obj);
|
||||
void Create(object obj, int depth);
|
||||
void SaveAll<T>(Transaction transaction, IEnumerator<T> objects);
|
||||
|
||||
void Update(object obj);
|
||||
@ -22,54 +21,47 @@ public interface IObjectDbSession : IObjectContainer
|
||||
|
||||
public class ObjectDbSession : ObjectContainerSession, IObjectDbSession
|
||||
{
|
||||
private NoCahceRefrenceSystem _noCacheRefSystem;
|
||||
|
||||
public ObjectDbSession(ObjectContainerBase server)
|
||||
: base(server, server.NewTransaction(server.SystemTransaction(), new NoCahceRefrenceSystem(), false))
|
||||
: base(server, server.NewTransaction(server.SystemTransaction(), new NoCacheReferenceSystem(), false))
|
||||
{
|
||||
_transaction.SetOutSideRepresentation(this);
|
||||
_noCacheRefSystem = (NoCahceRefrenceSystem)_transaction.ReferenceSystem();
|
||||
}
|
||||
|
||||
public override void Store(object obj)
|
||||
{
|
||||
throw new InvalidOperationException("Store is not supported. please use Save() or Update()");
|
||||
throw new InvalidOperationException("Store is not supported. please use Create() or Update()");
|
||||
}
|
||||
|
||||
public override void StoreAll(Transaction transaction, IEnumerator objects)
|
||||
{
|
||||
throw new InvalidOperationException("Store is not supported. please use Save() or Update()");
|
||||
throw new InvalidOperationException("Store is not supported. please use Create() or Update()");
|
||||
|
||||
}
|
||||
|
||||
public override void Store(object obj, int depth)
|
||||
{
|
||||
throw new InvalidOperationException("Store is not supported. please use Save() or Update()");
|
||||
throw new InvalidOperationException("Store is not supported. please use Create() or Update()");
|
||||
}
|
||||
|
||||
public void Save(object obj)
|
||||
public void Create(object obj)
|
||||
{
|
||||
ValidateSave(obj);
|
||||
ValidateCreate(obj);
|
||||
base.Store(obj);
|
||||
Commit();
|
||||
}
|
||||
|
||||
public void Save(object obj, int depth)
|
||||
public void Create(object obj, int depth)
|
||||
{
|
||||
ValidateSave(obj);
|
||||
ValidateCreate(obj);
|
||||
base.Store(obj, depth);
|
||||
Commit();
|
||||
|
||||
}
|
||||
|
||||
public void SaveAll<T>(Transaction transaction, IEnumerator<T> objects)
|
||||
{
|
||||
var obj = objects.ToIEnumerable().ToList();
|
||||
obj.ForEach(c => ValidateSave(c));
|
||||
obj.ForEach(c => ValidateCreate(c));
|
||||
|
||||
base.StoreAll(transaction, obj.GetEnumerator());
|
||||
Commit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -77,14 +69,12 @@ public void Update(object obj)
|
||||
{
|
||||
ValidateUpdate(obj);
|
||||
base.Store(obj);
|
||||
Commit();
|
||||
}
|
||||
|
||||
public void Update(object obj, int depth)
|
||||
{
|
||||
ValidateUpdate(obj);
|
||||
base.Store(obj, depth);
|
||||
Commit();
|
||||
}
|
||||
|
||||
public void UpdateAll<T>(Transaction transaction, IEnumerator<T> objects)
|
||||
@ -93,7 +83,6 @@ public void UpdateAll<T>(Transaction transaction, IEnumerator<T> objects)
|
||||
obj.ForEach(c => ValidateUpdate(c));
|
||||
|
||||
base.StoreAll(transaction, obj.GetEnumerator());
|
||||
Commit();
|
||||
}
|
||||
|
||||
public void UpdateAll(Transaction transaction, IEnumerator objects)
|
||||
@ -101,12 +90,8 @@ public void UpdateAll(Transaction transaction, IEnumerator objects)
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public new void Purge()
|
||||
{
|
||||
_noCacheRefSystem.Reset();
|
||||
}
|
||||
|
||||
private void ValidateSave(object obj)
|
||||
private void ValidateCreate(object obj)
|
||||
{
|
||||
if (IsAttached(obj))
|
||||
{
|
25
NzbDrone.Core/Datastore/ObjectDbSessionFactory.cs
Normal file
25
NzbDrone.Core/Datastore/ObjectDbSessionFactory.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.Linq;
|
||||
using Db4objects.Db4o;
|
||||
using Db4objects.Db4o.IO;
|
||||
using Db4objects.Db4o.Internal;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public class ObjectDbSessionFactory
|
||||
{
|
||||
public IObjectDbSession Create(IStorage storage = null, string dbName = "nzbdrone.db4o")
|
||||
{
|
||||
if (storage == null)
|
||||
{
|
||||
storage = new FileStorage();
|
||||
}
|
||||
|
||||
var config = Db4oEmbedded.NewConfiguration();
|
||||
config.File.Storage = storage;
|
||||
|
||||
|
||||
var objectContainer = Db4oEmbedded.OpenFile(config, dbName);
|
||||
return new ObjectDbSession((ObjectContainerBase)objectContainer);
|
||||
}
|
||||
}
|
||||
}
|
@ -235,8 +235,8 @@
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="ContainerExtentions.cs" />
|
||||
<Compile Include="Datastore\ConnectionFactory.cs" />
|
||||
<Compile Include="Datastore\NoCahceRefrenceSystem.cs" />
|
||||
<Compile Include="Datastore\IObjectDbSession.cs" />
|
||||
<Compile Include="Datastore\NoCacheReferenceSystem.cs" />
|
||||
<Compile Include="Datastore\ObjectDbSession.cs" />
|
||||
<Compile Include="Datastore\MigrationLogger.cs" />
|
||||
<Compile Include="Datastore\MigrationsHelper.cs" />
|
||||
<Compile Include="Datastore\CustomeMapper.cs" />
|
||||
@ -270,6 +270,7 @@
|
||||
<Compile Include="Datastore\Migrations\Migration20121223.cs" />
|
||||
<Compile Include="Datastore\Migrations\NzbDroneMigration.cs" />
|
||||
<Compile Include="Datastore\Migrations\SchemaInfo.cs" />
|
||||
<Compile Include="Datastore\ObjectDbSessionFactory.cs" />
|
||||
<Compile Include="Datastore\PetaPoco\EpisodeSeasonRelator.cs" />
|
||||
<Compile Include="Fluent.cs" />
|
||||
<Compile Include="Helpers\Converters\EpochDateTimeConverter.cs" />
|
||||
|
@ -366,7 +366,7 @@
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>59157</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>17584</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:62182/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
|
Loading…
Reference in New Issue
Block a user