less intrusive cache prevention.

more tests.
pull/4/head
kay.one 12 years ago
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 @@ namespace NzbDrone.Core.Test.Datastore
[SetUp]
public void SetUp()
{
WithObjectDb();
WithObjectDb(false);
}
[Test]
@ -27,7 +23,7 @@ namespace NzbDrone.Core.Test.Datastore
var series = Builder<Series>.CreateNew().Build();
ObjDb.Save(series);
ObjDb.Create(series);
ObjDb.Ext().Purge();
@ -41,14 +37,76 @@ namespace NzbDrone.Core.Test.Datastore
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 @@ namespace NzbDrone.Core.Test.Framework
Mocker.SetConstant(Db);
}
protected void WithObjectDb()
protected void WithObjectDb(bool memory = true)
{
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 @@ namespace NzbDrone.Core.Datastore
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);
}
}
}

@ -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.Collections.Generic;
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 @@ namespace NzbDrone.Core.Datastore
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 @@ namespace NzbDrone.Core.Datastore
{
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 @@ namespace NzbDrone.Core.Datastore
obj.ForEach(c => ValidateUpdate(c));
base.StoreAll(transaction, obj.GetEnumerator());
Commit();
}
public void UpdateAll(Transaction transaction, IEnumerator objects)
@ -101,12 +90,8 @@ namespace NzbDrone.Core.Datastore
throw new NotImplementedException();
}
public new void Purge()
{
_noCacheRefSystem.Reset();
}
private void ValidateSave(object obj)
private void ValidateCreate(object obj)
{
if (IsAttached(obj))
{

@ -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…
Cancel
Save