added Marr.Data.Mapping

pull/3113/head
kay.one 12 years ago
parent 4bb4faf626
commit 6dd56114e3

@ -3,14 +3,14 @@ using System.Data;
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Marr.Data.Mapping;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using ServiceStack.OrmLite;
namespace NzbDrone.Core.Test.Datastore namespace NzbDrone.Core.Test.Datastore
{ {
public class BaiscType : ModelBase public class BasicType : ModelBase
{ {
public string Name { get; set; } public string Name { get; set; }
public string Tilte { get; set; } public string Tilte { get; set; }
@ -18,26 +18,33 @@ namespace NzbDrone.Core.Test.Datastore
} }
[TestFixture] [TestFixture]
public class BasicRepositoryFixture : DbTest<BasicRepository<BaiscType>,BaiscType> public class
BasicRepositoryFixture : DbTest<BasicRepository<BasicType>, BasicType>
{ {
private BaiscType _baiscType; private BasicType _basicType;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_baiscType = Builder<BaiscType> _basicType = Builder<BasicType>
.CreateNew() .CreateNew()
.With(c => c.Id = 0) .With(c => c.Id = 0)
.Build(); .Build();
Mocker.Resolve<IDbConnection>().CreateTable<BaiscType>(); var mapping = new FluentMappings(true);
mapping.Entity<BasicType>()
.Columns.AutoMapSimpleTypeProperties()
.For(c => c.Id).SetAutoIncrement()
.SetPrimaryKey();
} }
[Test] [Test]
public void should_be_able_to_add() public void should_be_able_to_add()
{ {
Subject.Insert(_baiscType); Subject.Insert(_basicType);
Subject.All().Should().HaveCount(1); Subject.All().Should().HaveCount(1);
} }
@ -46,21 +53,21 @@ namespace NzbDrone.Core.Test.Datastore
[Test] [Test]
public void should_be_able_to_delete_model() public void should_be_able_to_delete_model()
{ {
Subject.Insert(_baiscType); Subject.Insert(_basicType);
Subject.All().Should().HaveCount(1); Subject.All().Should().HaveCount(1);
Subject.Delete(_baiscType.Id); Subject.Delete(_basicType.Id);
Subject.All().Should().BeEmpty(); Subject.All().Should().BeEmpty();
} }
[Test] [Test]
public void should_be_able_to_find_by_id() public void should_be_able_to_find_by_id()
{ {
Subject.Insert(_baiscType); Subject.Insert(_basicType);
Subject.Get(_baiscType.Id) Subject.Get(_basicType.Id)
.ShouldHave() .ShouldHave()
.AllProperties() .AllProperties()
.EqualTo(_baiscType); .EqualTo(_basicType);
} }
[Test] [Test]

@ -7,32 +7,29 @@ using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using ServiceStack.OrmLite;
namespace NzbDrone.Core.Test.Datastore namespace NzbDrone.Core.Test.Datastore
{ {
[TestFixture] [TestFixture]
public class ObjectDatabaseFixture : DbTest<BasicRepository<BaiscType>, BaiscType> public class ObjectDatabaseFixture : DbTest<BasicRepository<BasicType>, BasicType>
{ {
private BaiscType _sampleType; private BasicType _sampleType;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
_sampleType = Builder<BaiscType> _sampleType = Builder<BasicType>
.CreateNew() .CreateNew()
.With(s => s.Id = 0) .With(s => s.Id = 0)
.Build(); .Build();
Mocker.Resolve<IDbConnection>().CreateTable<BaiscType>();
} }
[Test] [Test]
public void should_be_able_to_write_to_database() public void should_be_able_to_write_to_database()
{ {
Subject.Insert(_sampleType); Subject.Insert(_sampleType);
Db.All<BaiscType>().Should().HaveCount(1); Db.All<BasicType>().Should().HaveCount(1);
} }
[Test] [Test]
@ -52,7 +49,7 @@ namespace NzbDrone.Core.Test.Datastore
[Test] [Test]
public void should_be_able_to_store_empty_list() public void should_be_able_to_store_empty_list()
{ {
var series = new List<BaiscType>(); var series = new List<BasicType>();
Subject.InsertMany(series); Subject.InsertMany(series);
} }
@ -71,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore
_sampleType.Id = 0; _sampleType.Id = 0;
Subject.Insert(_sampleType); Subject.Insert(_sampleType);
Db.All<BaiscType>().Should().HaveCount(1); Db.All<BasicType>().Should().HaveCount(1);
_sampleType.Id.Should().Be(1); _sampleType.Id.Should().Be(1);
} }
@ -83,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore
{ {
_sampleType.Id = 0; _sampleType.Id = 0;
Subject.Insert(_sampleType); Subject.Insert(_sampleType);
var item = Db.All<BaiscType>(); var item = Db.All<BasicType>();
item.Should().HaveCount(1); item.Should().HaveCount(1);
item.First().Id.Should().NotBe(0); item.First().Id.Should().NotBe(0);
@ -95,7 +92,7 @@ namespace NzbDrone.Core.Test.Datastore
public void should_be_able_to_find_object_by_id() public void should_be_able_to_find_object_by_id()
{ {
Subject.Insert(_sampleType); Subject.Insert(_sampleType);
var item = Db.All<BaiscType>().Single(c => c.Id == _sampleType.Id); var item = Db.All<BasicType>().Single(c => c.Id == _sampleType.Id);
item.Id.Should().NotBe(0); item.Id.Should().NotBe(0);
item.Id.Should().Be(_sampleType.Id); item.Id.Should().Be(_sampleType.Id);
@ -105,7 +102,7 @@ namespace NzbDrone.Core.Test.Datastore
[Test] [Test]
public void update_field_should_only_update_that_filed() public void update_field_should_only_update_that_filed()
{ {
var childModel = new BaiscType var childModel = new BasicType
{ {
Address = "Address", Address = "Address",
Name = "Name", Name = "Name",
@ -121,9 +118,9 @@ namespace NzbDrone.Core.Test.Datastore
Subject.UpdateFields(childModel, t => t.Name); Subject.UpdateFields(childModel, t => t.Name);
Db.All<BaiscType>().Single().Address.Should().Be("Address"); Db.All<BasicType>().Single().Address.Should().Be("Address");
Db.All<BaiscType>().Single().Name.Should().Be("B"); Db.All<BasicType>().Single().Name.Should().Be("B");
Db.All<BaiscType>().Single().Tilte.Should().Be("Title"); Db.All<BasicType>().Single().Tilte.Should().Be("Title");
} }

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.IO;
using System.Linq; using System.Linq;
using Marr.Data;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using ServiceStack.OrmLite;
namespace NzbDrone.Core.Test.Framework namespace NzbDrone.Core.Test.Framework
{ {
@ -61,8 +62,12 @@ namespace NzbDrone.Core.Test.Framework
public abstract class DbTest : CoreTest public abstract class DbTest : CoreTest
{ {
private IDatabase _db; private string _dbName;
protected IDatabase Db
private ITestDatabase _db;
private IDatabase _database;
protected ITestDatabase Db
{ {
get get
{ {
@ -75,10 +80,15 @@ namespace NzbDrone.Core.Test.Framework
private void WithObjectDb(bool memory = true) private void WithObjectDb(bool memory = true)
{ {
_dbName = DateTime.Now.Ticks.ToString() + ".db";
MapRepository.Instance.EnableTraceLogging = true;
var factory = new DbFactory(); var factory = new DbFactory();
var dbConnection = factory.Create(); _database = factory.Create(_dbName);
_db = new TestDatabase(dbConnection); _db = new TestTestDatabase(_database);
Mocker.SetConstant(dbConnection); Mocker.SetConstant(_database);
} }
[SetUp] [SetUp]
@ -87,51 +97,68 @@ namespace NzbDrone.Core.Test.Framework
WithObjectDb(); WithObjectDb();
} }
[TearDown]
public void TearDown()
{
var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.db");
foreach (var file in files)
{
try
{
File.Delete(file);
}
catch (Exception)
{
}
}
}
} }
public interface IDatabase public interface ITestDatabase
{ {
void InsertMany<T>(IEnumerable<T> items) where T : new(); void InsertMany<T>(IEnumerable<T> items) where T : ModelBase, new();
void Insert<T>(T item) where T : new(); void Insert<T>(T item) where T : ModelBase, new();
IEnumerable<T> All<T>() where T : new(); IEnumerable<T> All<T>() where T : ModelBase, new();
void Update<T>(T childModel) where T : new(); void Update<T>(T childModel) where T : ModelBase, new();
void Delete<T>(T childModel) where T : new(); void Delete<T>(T childModel) where T : ModelBase, new();
} }
public class TestDatabase : IDatabase public class TestTestDatabase : ITestDatabase
{ {
private readonly IDbConnection _dbConnection; private readonly IDatabase _dbConnection;
public TestDatabase(IDbConnection dbConnection) public TestTestDatabase(IDatabase dbConnection)
{ {
_dbConnection = dbConnection; _dbConnection = dbConnection;
} }
public void InsertMany<T>(IEnumerable<T> items) where T : new() public void InsertMany<T>(IEnumerable<T> items) where T : ModelBase, new()
{ {
_dbConnection.InsertAll(items); new BasicRepository<T>(_dbConnection).InsertMany(items.ToList());
} }
public void Insert<T>(T item) where T : new() public void Insert<T>(T item) where T : ModelBase, new()
{ {
_dbConnection.Insert(item); new BasicRepository<T>(_dbConnection).Insert(item);
} }
public IEnumerable<T> All<T>() where T : new() public IEnumerable<T> All<T>() where T : ModelBase, new()
{ {
return _dbConnection.Select<T>(); return new BasicRepository<T>(_dbConnection).All();
} }
public void Update<T>(T childModel) where T : new() public void Update<T>(T childModel) where T : ModelBase, new()
{ {
_dbConnection.Update(childModel); new BasicRepository<T>(_dbConnection).Update(childModel);
} }
public void Delete<T>(T childModel) where T : new() public void Delete<T>(T childModel) where T : ModelBase, new()
{ {
_dbConnection.Delete(childModel); new BasicRepository<T>(_dbConnection).Delete(childModel);
} }
} }
} }

@ -77,6 +77,9 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\FluentAssertions.2.0.0.1\lib\net40\FluentAssertions.dll</HintPath> <HintPath>..\packages\FluentAssertions.2.0.0.1\lib\net40\FluentAssertions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Marr.Data">
<HintPath>..\packages\MarrDataMapper.3.17.4747.34302\lib\Marr.Data.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
@ -89,9 +92,6 @@
<Reference Include="Microsoft.Practices.Unity.Configuration"> <Reference Include="Microsoft.Practices.Unity.Configuration">
<HintPath>..\packages\Unity.2.1.505.2\lib\NET35\Microsoft.Practices.Unity.Configuration.dll</HintPath> <HintPath>..\packages\Unity.2.1.505.2\lib\NET35\Microsoft.Practices.Unity.Configuration.dll</HintPath>
</Reference> </Reference>
<Reference Include="Mono.Data.Sqlite">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\Mono.Data.Sqlite.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference> </Reference>
@ -114,26 +114,6 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll</HintPath> <HintPath>..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll</HintPath>
</Reference> </Reference>
<Reference Include="ServiceStack.Common, Version=3.9.42.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.42\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces">
<HintPath>..\packages\ServiceStack.Common.3.9.42\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.OrmLite">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\ServiceStack.OrmLite.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.OrmLite.Sqlite">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\ServiceStack.OrmLite.Sqlite.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.42.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.42\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SignalR, Version=0.5.1.10822, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="SignalR, Version=0.5.1.10822, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SignalR.Server.0.5.3\lib\net40\SignalR.dll</HintPath> <HintPath>..\packages\SignalR.Server.0.5.3\lib\net40\SignalR.dll</HintPath>

@ -11,9 +11,6 @@
<package id="NLog" version="2.0.0.2000" /> <package id="NLog" version="2.0.0.2000" />
<package id="NUnit" version="2.6.2" targetFramework="net40" /> <package id="NUnit" version="2.6.2" targetFramework="net40" />
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" /> <package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
<package id="ServiceStack.Common" version="3.9.42" targetFramework="net40" />
<package id="ServiceStack.OrmLite.Sqlite.Mono" version="3.9.42" targetFramework="net40" />
<package id="ServiceStack.Text" version="3.9.42" targetFramework="net40" />
<package id="SignalR.Server" version="0.5.3" targetFramework="net40" /> <package id="SignalR.Server" version="0.5.3" targetFramework="net40" />
<package id="Unity" version="2.1.505.2" targetFramework="net40" /> <package id="Unity" version="2.1.505.2" targetFramework="net40" />
</packages> </packages>

@ -1,11 +1,9 @@
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using ServiceStack.DataAnnotations;
namespace NzbDrone.Core.Configuration namespace NzbDrone.Core.Configuration
{ {
public class Config : ModelBase public class Config : ModelBase
{ {
[Index(Unique = true)]
public string Key { get; set; } public string Key { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }

@ -12,7 +12,7 @@ namespace NzbDrone.Core.Configuration
public class ConfigRepository : BasicRepository<Config>, IConfigRepository public class ConfigRepository : BasicRepository<Config>, IConfigRepository
{ {
public ConfigRepository(IDbConnection database) public ConfigRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
@ -20,7 +20,7 @@ namespace NzbDrone.Core.Configuration
public Config Get(string key) public Config Get(string key)
{ {
return SingleOrDefault(c => c.Key == key); return Queryable().SingleOrDefault(c => c.Key == key);
} }

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using ServiceStack.OrmLite; using Marr.Data;
using Marr.Data.QGen;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
@ -11,12 +13,8 @@ namespace NzbDrone.Core.Datastore
{ {
IEnumerable<TModel> All(); IEnumerable<TModel> All();
int Count(); int Count();
bool Any(Expression<Func<TModel, bool>> predicate);
TModel Get(int id); TModel Get(int id);
TModel Single(Expression<Func<TModel, bool>> predicate);
TModel SingleOrDefault(); TModel SingleOrDefault();
TModel SingleOrDefault(Expression<Func<TModel, bool>> predicate);
List<TModel> Where(Expression<Func<TModel, bool>> predicate);
TModel Insert(TModel model); TModel Insert(TModel model);
TModel Update(TModel model); TModel Update(TModel model);
TModel Upsert(TModel model); TModel Upsert(TModel model);
@ -29,38 +27,39 @@ namespace NzbDrone.Core.Datastore
bool HasItems(); bool HasItems();
void DeleteMany(IEnumerable<int> ids); void DeleteMany(IEnumerable<int> ids);
void UpdateFields<TKey>(TModel model, Expression<Func<TModel, TKey>> onlyFields); void UpdateFields<TKey>(TModel model, Expression<Func<TModel, TKey>> onlyFields);
List<TModel> Where(SqlExpressionVisitor<TModel> expression);
} }
public class BasicRepository<TModel> : IBasicRepository<TModel> where TModel : ModelBase, new() public class BasicRepository<TModel> : IBasicRepository<TModel> where TModel : ModelBase, new()
{ {
private readonly IDbConnection _database; private readonly IDataMapper _dataMapper;
public BasicRepository(IDbConnection database) public BasicRepository(IDatabase database)
{ {
_database = database; _dataMapper = database.DataMapper;
} }
public IEnumerable<TModel> All() protected QueryBuilder<TModel> Queryable()
{ {
return _database.Select<TModel>(); return _dataMapper.Query<TModel>();
} }
public int Count() public IEnumerable<TModel> All()
{ {
return (int)_database.Count<TModel>(); return _dataMapper.Query<TModel>().ToList();
} }
public bool Any(Expression<Func<TModel, bool>> predicate) public int Count()
{ {
return _database.Exists<TModel>(predicate); return _dataMapper.Query<TModel>().Count();
} }
public TModel Get(int id) public TModel Get(int id)
{ {
try try
{ {
return _database.GetById<TModel>(id); var c = _dataMapper.Query<TModel>().FromTable(typeof(TModel).Name);
return null;
} }
catch (ArgumentNullException e) catch (ArgumentNullException e)
{ {
@ -69,36 +68,12 @@ namespace NzbDrone.Core.Datastore
} }
public TModel Single(Expression<Func<TModel, bool>> predicate)
{
return _database.Select(predicate).Single();
}
public TModel SingleOrDefault() public TModel SingleOrDefault()
{ {
return All().Single(); return All().Single();
} }
public TModel Single()
{
throw new System.NotImplementedException();
}
public TModel SingleOrDefault(Expression<Func<TModel, bool>> predicate)
{
return _database.Select(predicate).SingleOrDefault();
}
public List<TModel> Where(Expression<Func<TModel, bool>> predicate)
{
return _database.Select(predicate);
}
public List<TModel> Where(SqlExpressionVisitor<TModel> expression)
{
return _database.Select(expression);
}
public TModel Insert(TModel model) public TModel Insert(TModel model)
{ {
if (model.Id != 0) if (model.Id != 0)
@ -106,8 +81,7 @@ namespace NzbDrone.Core.Datastore
throw new InvalidOperationException("Can't insert model with existing ID"); throw new InvalidOperationException("Can't insert model with existing ID");
} }
_database.Insert(model); var id = _dataMapper.Insert(model);
model.Id = (int)_database.GetLastInsertId();
return model; return model;
} }
@ -118,56 +92,61 @@ namespace NzbDrone.Core.Datastore
throw new InvalidOperationException("Can't update model with ID 0"); throw new InvalidOperationException("Can't update model with ID 0");
} }
_database.Update(model); _dataMapper.Update(model, c => c.Id == model.Id);
return model; return model;
} }
public void Delete(TModel model) public void Delete(TModel model)
{ {
_database.Delete(model); _dataMapper.Delete<TModel>(c => c.Id == model.Id);
} }
public void InsertMany(IList<TModel> models) public void InsertMany(IList<TModel> models)
{ {
_database.InsertAll(models); foreach (var model in models)
{
Insert(model);
}
} }
public void UpdateMany(IList<TModel> models) public void UpdateMany(IList<TModel> models)
{ {
_database.UpdateAll(models); foreach (var model in models)
{
Update(model);
}
} }
public void DeleteMany(List<TModel> models) public void DeleteMany(List<TModel> models)
{ {
_database.DeleteAll(models); models.ForEach(Delete);
} }
public TModel Upsert(TModel model) public TModel Upsert(TModel model)
{ {
if (model.Id == 0) if (model.Id == 0)
{ {
_database.Insert(model); Insert(model);
model.Id = (int)_database.GetLastInsertId();
return model; return model;
} }
_database.Update(model); Update(model);
return model; return model;
} }
public void Delete(int id) public void Delete(int id)
{ {
_database.DeleteById<TModel>(id); _dataMapper.Delete<TModel>(c => c.Id == id);
} }
public void DeleteMany(IEnumerable<int> ids) public void DeleteMany(IEnumerable<int> ids)
{ {
_database.DeleteByIds<TModel>(ids); ids.ToList().ForEach(Delete);
} }
public void Purge() public void Purge()
{ {
_database.DeleteAll<TModel>(); _dataMapper.Delete<TModel>(c => c.Id > -1);
} }
public bool HasItems() public bool HasItems()
@ -182,7 +161,7 @@ namespace NzbDrone.Core.Datastore
throw new InvalidOperationException("Attempted to updated model without ID"); throw new InvalidOperationException("Attempted to updated model without ID");
} }
_database.UpdateOnly(model, onlyFields, m => m.Id == model.Id); // _database.UpdateOnly(model, onlyFields, m => m.Id == model.Id);
} }
} }
} }

@ -0,0 +1,21 @@
using System;
using Marr.Data;
namespace NzbDrone.Core.Datastore
{
public interface IDatabase
{
IDataMapper DataMapper { get; }
}
public class Database : IDatabase
{
public Database(IDataMapper dataMapper)
{
DataMapper = dataMapper;
}
public IDataMapper DataMapper { get; private set; }
}
}

@ -1,25 +1,21 @@
using System; using System;
using System.Data; using System.Data;
using ServiceStack.OrmLite; using Marr.Data;
using ServiceStack.OrmLite.Sqlite; using Mono.Data.Sqlite;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
public interface IDbFactory public interface IDbFactory
{ {
IDbConnection Create(string dbPath = null); IDatabase Create(string dbPath = null);
} }
public class DbFactory : IDbFactory public class DbFactory : IDbFactory
{ {
private const string MemoryConnectionString = "Data Source=:memory:;Version=3;New=True;"; private const string MemoryConnectionString = "Data Source=:memory:;Version=3;New=True;";
static DbFactory() public IDatabase Create(string dbPath = null)
{
OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider();
}
public IDbConnection Create(string dbPath = null)
{ {
var connectionString = MemoryConnectionString; var connectionString = MemoryConnectionString;
@ -29,15 +25,11 @@ namespace NzbDrone.Core.Datastore
} }
MigrationHelper.MigrateToLatest(connectionString, MigrationType.Main); MigrationHelper.MigrateToLatest(connectionString, MigrationType.Main);
var dataMapper = new DataMapper(SqliteFactory.Instance, connectionString);
return new Database(dataMapper);
}
OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider();
var dbFactory = new OrmLiteConnectionFactory(connectionString);
var connection = dbFactory.Open();
Migration.CreateTables(connection);
return connection;
}
private string GetConnectionString(string dbPath) private string GetConnectionString(string dbPath)
{ {

@ -1,22 +1,10 @@
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using ServiceStack.OrmLite;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
public static class Migration public static class Migration
{ {
public static void CreateTables(IDbConnection dbConnection)
{
var types = typeof(ModelBase).Assembly.GetTypes();
var models = types.Where(c => c.BaseType == typeof(ModelBase));
foreach (var model in models)
{
dbConnection.CreateTable(true, model);
}
}
} }
} }

@ -1,12 +1,12 @@
using System.Diagnostics; using System.Data;
using ServiceStack.DataAnnotations; using System.Diagnostics;
using Marr.Data;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
[DebuggerDisplay("{GetType()} ID = {Id}")] [DebuggerDisplay("{GetType()} ID = {Id}")]
public abstract class ModelBase public abstract class ModelBase
{ {
[AutoIncrement]
public int Id { get; set; } public int Id { get; set; }
} }
} }

@ -1,4 +1,5 @@
using System.Data; using System.Data;
using System.Linq;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.ExternalNotification namespace NzbDrone.Core.ExternalNotification
@ -10,14 +11,14 @@ namespace NzbDrone.Core.ExternalNotification
public class ExternalNotificationRepository : BasicRepository<ExternalNotificationDefinition>, IExternalNotificationRepository public class ExternalNotificationRepository : BasicRepository<ExternalNotificationDefinition>, IExternalNotificationRepository
{ {
public ExternalNotificationRepository(IDbConnection database) public ExternalNotificationRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public ExternalNotificationDefinition Get(string name) public ExternalNotificationDefinition Get(string name)
{ {
return SingleOrDefault(c => c.Name.ToLower() == name.ToLower()); return Queryable().SingleOrDefault(c => c.Name.ToLower() == name.ToLower());
} }
} }
} }

@ -14,21 +14,21 @@ namespace NzbDrone.Core.History
public class HistoryRepository : BasicRepository<History>, IHistoryRepository public class HistoryRepository : BasicRepository<History>, IHistoryRepository
{ {
public HistoryRepository(IDbConnection database) public HistoryRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public void Trim() public void Trim()
{ {
var oldIds = Where(c => c.Date < DateTime.Now.AddDays(-30).Date).Select(c => c.Id); var oldIds = Queryable().Where(c => c.Date < DateTime.Now.AddDays(-30).Date).Select(c => c.Id);
DeleteMany(oldIds); DeleteMany(oldIds);
} }
public QualityModel GetBestQualityInHistory(int episodeId) public QualityModel GetBestQualityInHistory(int episodeId)
{ {
var history = Where(c => c.EpisodeId == episodeId) var history = Queryable().Where(c => c.EpisodeId == episodeId)
.OrderByDescending(c => c.Quality).FirstOrDefault(); .OrderByDescending(c => c.Quality).FirstOrDefault();
if (history != null) if (history != null)

@ -1,5 +1,6 @@
using System; using System;
using System.Data; using System.Data;
using System.Linq;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
@ -11,14 +12,14 @@ namespace NzbDrone.Core.Indexers
public class IndexerRepository : BasicRepository<Indexer>, IIndexerRepository public class IndexerRepository : BasicRepository<Indexer>, IIndexerRepository
{ {
public IndexerRepository(IDbConnection database) public IndexerRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public Indexer Find(Type type) public Indexer Find(Type type)
{ {
return Single(i => i.Type == type.ToString()); return Queryable().Single(i => i.Type == type.ToString());
} }
} }
} }

@ -14,13 +14,13 @@ namespace NzbDrone.Core.Indexers
public class NewznabRepository : BasicRepository<NewznabDefinition>, INewznabRepository public class NewznabRepository : BasicRepository<NewznabDefinition>, INewznabRepository
{ {
public NewznabRepository(IDbConnection database) : base(database) public NewznabRepository(IDatabase database) : base(database)
{ {
} }
public IEnumerable<NewznabDefinition> Enabled() public IEnumerable<NewznabDefinition> Enabled()
{ {
return Where(n => n.Enable); return Queryable().Where(n => n.Enabled);
} }
} }
} }

@ -12,14 +12,14 @@ namespace NzbDrone.Core.Instrumentation
public class LogRepository : BasicRepository<Log>, ILogRepository public class LogRepository : BasicRepository<Log>, ILogRepository
{ {
public LogRepository(IDbConnection database) public LogRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public void Trim() public void Trim()
{ {
var oldIds = Where(c => c.Time < DateTime.Now.AddDays(-30).Date).Select(c => c.Id); var oldIds = Queryable().Where(c => c.Time < DateTime.Now.AddDays(-30).Date).Select(c => c.Id);
DeleteMany(oldIds); DeleteMany(oldIds);
} }
} }

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
@ -19,7 +18,7 @@ namespace NzbDrone.Core.Jobs
private readonly IEnumerable<IJob> _jobs; private readonly IEnumerable<IJob> _jobs;
private readonly Logger _logger; private readonly Logger _logger;
public JobRepository(IDbConnection database, IEnumerable<IJob> jobs, Logger logger) public JobRepository(IDatabase database, IEnumerable<IJob> jobs, Logger logger)
: base(database) : base(database)
{ {
_jobs = jobs; _jobs = jobs;
@ -28,13 +27,13 @@ namespace NzbDrone.Core.Jobs
public JobDefinition GetDefinition(Type type) public JobDefinition GetDefinition(Type type)
{ {
return Single(c => c.Type == type.FullName); return Queryable().Single(c => c.TypeName == type.FullName);
} }
public IList<JobDefinition> GetPendingJobs() public IList<JobDefinition> GetPendingJobs()
{ {
return Where(c => c.Enable && c.LastExecution < DateTime.Now.AddMinutes(-c.Interval)).ToList(); return Queryable().Where(c => c.Enable && c.LastExecution < DateTime.Now.AddMinutes(-c.Interval)).ToList();
} }
public void Init() public void Init()
@ -73,4 +72,4 @@ namespace NzbDrone.Core.Jobs
} }
} }
} }
} }

@ -15,7 +15,7 @@ namespace NzbDrone.Core.MediaFiles
public class MediaFileRepository : BasicRepository<EpisodeFile>, IMediaFileRepository public class MediaFileRepository : BasicRepository<EpisodeFile>, IMediaFileRepository
{ {
public MediaFileRepository(IDbConnection database) public MediaFileRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
@ -23,17 +23,17 @@ namespace NzbDrone.Core.MediaFiles
public EpisodeFile GetFileByPath(string path) public EpisodeFile GetFileByPath(string path)
{ {
return SingleOrDefault(c => c.Path == path); return Queryable().SingleOrDefault(c => c.Path == path);
} }
public List<EpisodeFile> GetFilesBySeries(int seriesId) public List<EpisodeFile> GetFilesBySeries(int seriesId)
{ {
return Where(c => c.SeriesId == seriesId).ToList(); return Queryable().Where(c => c.SeriesId == seriesId).ToList();
} }
public List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber) public List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber)
{ {
return Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber).ToList(); return Queryable().Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber).ToList();
} }
} }

@ -132,6 +132,8 @@
</Reference> </Reference>
<Reference Include="FluentMigrator.Runner"> <Reference Include="FluentMigrator.Runner">
<HintPath>..\packages\FluentMigrator.1.0.6.0\tools\FluentMigrator.Runner.dll</HintPath> <HintPath>..\packages\FluentMigrator.1.0.6.0\tools\FluentMigrator.Runner.dll</HintPath>
<Reference Include="FastReflection">
<HintPath>..\packages\MarrDataMapper.3.17.4747.34302\lib\FastReflection.dll</HintPath>
</Reference> </Reference>
<Reference Include="Growl.Connector"> <Reference Include="Growl.Connector">
<HintPath>..\packages\Growl.0.6\lib\Growl.Connector.dll</HintPath> <HintPath>..\packages\Growl.0.6\lib\Growl.Connector.dll</HintPath>
@ -142,12 +144,16 @@
<Reference Include="Ionic.Zip"> <Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath> <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
</Reference> </Reference>
<Reference Include="Marr.Data">
<HintPath>..\packages\MarrDataMapper.3.17.4747.34302\lib\Marr.Data.dll</HintPath>
</Reference>
<Reference Include="MediaInfoDotNet"> <Reference Include="MediaInfoDotNet">
<HintPath>..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll</HintPath> <HintPath>..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="Mono.Data.Sqlite"> <Reference Include="Mono.Data.Sqlite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\Mono.Data.Sqlite.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Sqlite\Mono.Data.Sqlite.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
@ -163,21 +169,6 @@
<Reference Include="RestSharp"> <Reference Include="RestSharp">
<HintPath>..\packages\RestSharp.104.1\lib\net4\RestSharp.dll</HintPath> <HintPath>..\packages\RestSharp.104.1\lib\net4\RestSharp.dll</HintPath>
</Reference> </Reference>
<Reference Include="ServiceStack.Common">
<HintPath>..\packages\ServiceStack.Common.3.9.42\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces">
<HintPath>..\packages\ServiceStack.Common.3.9.42\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.OrmLite">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\ServiceStack.OrmLite.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.OrmLite.Sqlite">
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.42\lib\net35\ServiceStack.OrmLite.Sqlite.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text">
<HintPath>..\packages\ServiceStack.Text.3.9.42\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SignalR"> <Reference Include="SignalR">
<HintPath>..\packages\SignalR.Server.0.5.3\lib\net40\SignalR.dll</HintPath> <HintPath>..\packages\SignalR.Server.0.5.3\lib\net40\SignalR.dll</HintPath>
</Reference> </Reference>
@ -214,6 +205,7 @@
<Compile Include="Configuration\IConfigService.cs" /> <Compile Include="Configuration\IConfigService.cs" />
<Compile Include="Constants.cs" /> <Compile Include="Constants.cs" />
<Compile Include="ContainerExtensions.cs" /> <Compile Include="ContainerExtensions.cs" />
<Compile Include="Datastore\Database.cs" />
<Compile Include="Datastore\DbFactory.cs" /> <Compile Include="Datastore\DbFactory.cs" />
<Compile Include="Datastore\MigrationHelper.cs" /> <Compile Include="Datastore\MigrationHelper.cs" />
<Compile Include="Datastore\Migration.cs" /> <Compile Include="Datastore\Migration.cs" />
@ -610,4 +602,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>

@ -14,7 +14,7 @@ namespace NzbDrone.Core.Qualities
public class QualityProfileRepository : BasicRepository<QualityProfile>, IQualityProfileRepository public class QualityProfileRepository : BasicRepository<QualityProfile>, IQualityProfileRepository
{ {
public QualityProfileRepository(IDbConnection database) public QualityProfileRepository(IDatabase database)
: base(database) : base(database)
{ {
} }

@ -11,14 +11,14 @@ namespace NzbDrone.Core.Qualities
public class QualitySizeRepository : BasicRepository<QualitySize>, IQualitySizeRepository public class QualitySizeRepository : BasicRepository<QualitySize>, IQualitySizeRepository
{ {
public QualitySizeRepository(IDbConnection database) public QualitySizeRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public QualitySize GetByQualityId(int qualityId) public QualitySize GetByQualityId(int qualityId)
{ {
return Single(q => q.QualityId == qualityId); return Queryable().Single(q => q.QualityId == qualityId);
} }
} }
} }

@ -13,19 +13,19 @@ namespace NzbDrone.Core.ReferenceData
public class SceneMappingRepository : BasicRepository<SceneMapping>, ISceneMappingRepository public class SceneMappingRepository : BasicRepository<SceneMapping>, ISceneMappingRepository
{ {
public SceneMappingRepository(IDbConnection database) public SceneMappingRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public SceneMapping FindByTvdbId(int tvdbId) public SceneMapping FindByTvdbId(int tvdbId)
{ {
return SingleOrDefault(c => c.TvdbId == tvdbId); return Queryable().SingleOrDefault(c => c.TvdbId == tvdbId);
} }
public SceneMapping FindByCleanTitle(string cleanTitle) public SceneMapping FindByCleanTitle(string cleanTitle)
{ {
return SingleOrDefault(c => c.CleanTitle == cleanTitle); return Queryable().SingleOrDefault(c => c.CleanTitle == cleanTitle);
} }
} }
} }

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using ServiceStack.OrmLite;
namespace NzbDrone.Core.Tv namespace NzbDrone.Core.Tv
{ {
@ -18,33 +18,33 @@ namespace NzbDrone.Core.Tv
{ {
private readonly IDbConnection _database; private readonly IDbConnection _database;
public SeasonRepository(IDbConnection database) public SeasonRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public IList<int> GetSeasonNumbers(int seriesId) public IList<int> GetSeasonNumbers(int seriesId)
{ {
return _database.List<int>("SELECT SeasonNumber WHERE SeriesId = {0}", seriesId); return Queryable().Where(c => c.SeriesId == seriesId).Select(c => c.SeriesId).ToList();
} }
public Season Get(int seriesId, int seasonNumber) public Season Get(int seriesId, int seasonNumber)
{ {
return _database.Select<Season>(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber).Single(); return Queryable().Single(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber);
} }
public bool IsIgnored(int seriesId, int seasonNumber) public bool IsIgnored(int seriesId, int seasonNumber)
{ {
var season = _database.Select<Season>(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber).SingleOrDefault(); var season = Queryable().SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber);
if(season == null) return false; if (season == null) return false;
return season.Ignored; return season.Ignored;
} }
public List<Season> GetSeasonBySeries(int seriesId) public List<Season> GetSeasonBySeries(int seriesId)
{ {
return _database.Select<Season>(s => s.SeriesId == seriesId); return Queryable().Where(s => s.SeriesId == seriesId);
} }
} }
} }

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Tv namespace NzbDrone.Core.Tv
@ -15,29 +16,29 @@ namespace NzbDrone.Core.Tv
public class SeriesRepository : BasicRepository<Series>, ISeriesRepository public class SeriesRepository : BasicRepository<Series>, ISeriesRepository
{ {
public SeriesRepository(IDbConnection database) public SeriesRepository(IDatabase database)
: base(database) : base(database)
{ {
} }
public bool SeriesPathExists(string path) public bool SeriesPathExists(string path)
{ {
return Any(c => c.Path == path); return Queryable().Any(c => c.Path == path);
} }
public List<Series> Search(string title) public List<Series> Search(string title)
{ {
return Where(s => s.Title.Contains(title)); return Queryable().Where(s => s.Title.Contains(title));
} }
public Series GetByTitle(string cleanTitle) public Series GetByTitle(string cleanTitle)
{ {
return SingleOrDefault(s => s.CleanTitle.Equals(cleanTitle)); return Queryable().SingleOrDefault(s => s.CleanTitle.Equals(cleanTitle));
} }
public Series FindByTvdbId(int tvdbId) public Series FindByTvdbId(int tvdbId)
{ {
return SingleOrDefault(s => s.TvDbId.Equals(tvdbId)); return Queryable().SingleOrDefault(s => s.TvDbId.Equals(tvdbId));
} }
public void SetSeriesType(int seriesId, SeriesTypes seriesType) public void SetSeriesType(int seriesId, SeriesTypes seriesType)

@ -4,15 +4,13 @@
<package id="DotNetZip" version="1.9.1.8" /> <package id="DotNetZip" version="1.9.1.8" />
<package id="FluentMigrator" version="1.0.6.0" targetFramework="net40" /> <package id="FluentMigrator" version="1.0.6.0" targetFramework="net40" />
<package id="Growl" version="0.6" /> <package id="Growl" version="0.6" />
<package id="MarrDataMapper" version="3.17.4747.34302" targetFramework="net40" />
<package id="MediaInfoNet" version="0.3" targetFramework="net40" /> <package id="MediaInfoNet" version="0.3" targetFramework="net40" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" /> <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" /> <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
<package id="NLog" version="2.0.0.2000" /> <package id="NLog" version="2.0.0.2000" />
<package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" /> <package id="Prowlin" version="0.9.4456.26422" targetFramework="net40" />
<package id="RestSharp" version="104.1" targetFramework="net40" /> <package id="RestSharp" version="104.1" targetFramework="net40" />
<package id="ServiceStack.Common" version="3.9.42" targetFramework="net40" />
<package id="ServiceStack.OrmLite.Sqlite.Mono" version="3.9.42" targetFramework="net40" />
<package id="ServiceStack.Text" version="3.9.42" targetFramework="net40" />
<package id="SignalR.Hosting.Common" version="0.5.3" targetFramework="net40" /> <package id="SignalR.Hosting.Common" version="0.5.3" targetFramework="net40" />
<package id="SignalR.Server" version="0.5.3" targetFramework="net40" /> <package id="SignalR.Server" version="0.5.3" targetFramework="net40" />
<package id="System.Data.SQLite.x86" version="1.0.84.0" targetFramework="net40" /> <package id="System.Data.SQLite.x86" version="1.0.84.0" targetFramework="net40" />

@ -2,6 +2,7 @@
<FileVersion>1</FileVersion> <FileVersion>1</FileVersion>
<AutoEnableOnStartup>True</AutoEnableOnStartup> <AutoEnableOnStartup>True</AutoEnableOnStartup>
<AllowParallelTestExecution>true</AllowParallelTestExecution> <AllowParallelTestExecution>true</AllowParallelTestExecution>
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit> <FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
<FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio> <FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio>
<FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec> <FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>

Loading…
Cancel
Save