schema updates

pull/4/head
kay.one 11 years ago committed by kayone
parent 1e88d2b7c3
commit 0eec2cd5f7

@ -12,7 +12,7 @@ namespace NzbDrone.Api.Test.ClientSchemaTests
[Test]
public void should_return_field_for_every_property()
{
var schema = SchemaBuilder.GenerateSchema(new TestModel());
var schema = SchemaBuilder.ToSchema(new TestModel());
schema.Should().HaveCount(2);
}
@ -26,7 +26,7 @@ namespace NzbDrone.Api.Test.ClientSchemaTests
LastName = "Poop"
};
var schema = SchemaBuilder.GenerateSchema(model);
var schema = SchemaBuilder.ToSchema(model);
schema.Should().Contain(c => c.Order == 1 && c.Name == "LastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && (string) c.Value == "Poop");
schema.Should().Contain(c => c.Order == 0 && c.Name == "FirstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && (string) c.Value == "Bob");

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Reflection;
using NzbDrone.Core.Annotations;
@ -8,8 +10,10 @@ namespace NzbDrone.Api.ClientSchema
{
public static class SchemaBuilder
{
public static List<Field> GenerateSchema(object model)
public static List<Field> ToSchema(object model)
{
Ensure.That(() => model).IsNotNull();
var properties = model.GetType().GetSimpleProperties();
var result = new List<Field>(properties.Count);
@ -50,10 +54,53 @@ namespace NzbDrone.Api.ClientSchema
}
public static object ReadFormSchema(List<Field> fields, Type targetType)
{
var properties = targetType.GetSimpleProperties();
var target = Activator.CreateInstance(targetType);
foreach (var propertyInfo in properties)
{
var fieldAttribute = propertyInfo.GetAttribute<FieldDefinitionAttribute>(false);
if (fieldAttribute != null)
{
var field = fields.Find(f => f.Name == propertyInfo.Name);
if (propertyInfo.PropertyType == typeof(Int32))
{
var intValue = Convert.ToInt32(field.Value);
propertyInfo.SetValue(target, intValue, null);
}
else if (propertyInfo.PropertyType == typeof(Nullable<Int32>))
{
var intValue = field.Value.ToString().ParseInt32();
propertyInfo.SetValue(target, intValue, null);
}
else
{
propertyInfo.SetValue(target, field.Value, null);
}
}
}
return target;
}
public static T ReadFormSchema<T>(List<Field> fields)
{
return (T)ReadFormSchema(fields, typeof (T));
}
private static List<SelectOption> GetSelectOptions(Type selectOptions)
{
var options = from Enum e in Enum.GetValues(selectOptions)
select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() };
select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() };
return options.OrderBy(o => o.Value).ToList();
}

@ -8,38 +8,6 @@ namespace NzbDrone.Api.ClientSchema
{
public static class SchemaDeserializer
{
public static T DeserializeSchema<T>(T model, List<Field> fields)
{
var properties = model.GetType().GetSimpleProperties();
foreach (var propertyInfo in properties)
{
var fieldAttribute = propertyInfo.GetAttribute<FieldDefinitionAttribute>(false);
if (fieldAttribute != null)
{
var field = fields.Find(f => f.Name == propertyInfo.Name);
if (propertyInfo.PropertyType == typeof (Int32))
{
var intValue = Convert.ToInt32(field.Value);
propertyInfo.SetValue(model, intValue, null);
}
else if (propertyInfo.PropertyType == typeof(Nullable<Int32>))
{
var intValue = field.Value.ToString().ParseInt32();
propertyInfo.SetValue(model, intValue, null);
}
else
{
propertyInfo.SetValue(model, field.Value, null);
}
}
}
return model;
}
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Common.Reflection;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.ThingiProvider;
using Omu.ValueInjecter;
@ -35,15 +36,15 @@ namespace NzbDrone.Api.Indexers
private List<IndexerResource> GetAll()
{
var indexers = _indexerService.All();
var indexerDefinitions = _indexerService.All();
var result = new List<IndexerResource>(indexers.Count);
var result = new List<IndexerResource>(indexerDefinitions.Count);
foreach (var indexer in indexers)
foreach (var definition in indexerDefinitions)
{
var indexerResource = new IndexerResource();
indexerResource.InjectFrom(indexer);
indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
indexerResource.InjectFrom(definition);
indexerResource.Fields = SchemaBuilder.ToSchema(definition.Settings);
result.Add(indexerResource);
}
@ -53,14 +54,14 @@ namespace NzbDrone.Api.Indexers
private int CreateIndexer(IndexerResource indexerResource)
{
var indexer = GetIndexer(indexerResource);
var indexer = GetDefinition(indexerResource);
indexer = _indexerService.Create(indexer);
return indexer.Id;
}
private void UpdateIndexer(IndexerResource indexerResource)
{
var indexer = GetIndexer(indexerResource);
var indexer = GetDefinition(indexerResource);
ValidateIndexer(indexer.Settings);
@ -78,12 +79,16 @@ namespace NzbDrone.Api.Indexers
}
}
private IndexerDefinition GetIndexer(IndexerResource indexerResource)
private IndexerDefinition GetDefinition(IndexerResource indexerResource)
{
var definition = new IndexerDefinition();
definition.InjectFrom(indexerResource);
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract);
if (indexerResource.Enable)
{
ValidateIndexer(definition.Settings);

@ -1,5 +1,6 @@
using System.Collections.Generic;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.Mapping;
using NzbDrone.Core.Indexers;
using Omu.ValueInjecter;
@ -18,6 +19,9 @@ namespace NzbDrone.Api.Indexers
private List<IndexerResource> GetSchema()
{
var indexers = _indexerService.All().InjectTo<List<IndexerResource>>();
/* var indexers = _indexerService.Schema();
var result = new List<IndexerResource>(indexers.Count);
@ -33,7 +37,7 @@ namespace NzbDrone.Api.Indexers
return result;*/
return null;
return indexers;
}
}
}

@ -4,6 +4,7 @@ using System.Linq;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.REST;
using NzbDrone.Common.Reflection;
using NzbDrone.Core.Notifications;
using Omu.ValueInjecter;
@ -39,7 +40,7 @@ namespace NzbDrone.Api.Notifications
{
var notificationResource = new NotificationResource();
notificationResource.InjectFrom(notification);
notificationResource.Fields = SchemaBuilder.GenerateSchema(notification.Settings);
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant());
result.Add(notificationResource);
@ -79,7 +80,10 @@ namespace NzbDrone.Api.Notifications
}
notification.InjectFrom(notificationResource);
notification.Settings = SchemaDeserializer.DeserializeSchema(notification.Settings, notificationResource.Fields);
//var configType = ReflectionExtensions.CoreAssembly.FindTypeByName(notification)
//notification.Settings = SchemaBuilder.ReadFormSchema(notification.Settings, notificationResource.Fields);
return notification;
}

@ -28,7 +28,7 @@ namespace NzbDrone.Api.Notifications
{
var notificationResource = new NotificationResource();
notificationResource.InjectFrom(notification);
notificationResource.Fields = SchemaBuilder.GenerateSchema(notification.Settings);
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant());
result.Add(notificationResource);

@ -7,6 +7,8 @@ namespace NzbDrone.Common.Reflection
{
public static class ReflectionExtensions
{
public static readonly Assembly CoreAssembly = Assembly.Load("NzbDrone.Core");
public static List<PropertyInfo> GetSimpleProperties(this Type type)
{
var properties = type.GetProperties();
@ -58,6 +60,11 @@ namespace NzbDrone.Common.Reflection
return (T)attribute;
}
public static Type FindTypeByName(this Assembly assembly, string name)
{
return assembly.GetTypes().Single(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
}
public static bool HasAttribute<TAttribute>(this Type type)
{
return type.GetCustomAttributes(typeof(TAttribute), true).Any();

@ -0,0 +1,39 @@
using System;
using FluentAssertions;
using Marr.Data.Converters;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Converters;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Test.Datastore.Converters
{
[TestFixture]
public class ProviderSettingConverterFixture : CoreTest<ProviderSettingConverter>
{
[Test]
public void should_return_null_config_if_config_is_null()
{
var result = Subject.FromDB(new ConverterContext()
{
DbValue = DBNull.Value
});
result.Should().Be(NullConfig.Instance);
}
[TestCase(null)]
[TestCase("")]
public void should_return_null_config_if_config_is_empty(object dbValue)
{
var result = Subject.FromDB(new ConverterContext()
{
DbValue = dbValue
});
result.Should().Be(NullConfig.Instance);
}
}
}

@ -102,6 +102,7 @@
<Compile Include="DataAugmentationFixture\Scene\SceneMappingProxyFixture.cs" />
<Compile Include="DataAugmentationFixture\Scene\SceneMappingServiceFixture.cs" />
<Compile Include="Datastore\BasicRepositoryFixture.cs" />
<Compile Include="Datastore\Converters\ProviderSettingConverterFixture.cs" />
<Compile Include="Datastore\DatabaseRelationshipFixture.cs" />
<Compile Include="Datastore\MappingExtentionFixture.cs" />
<Compile Include="Datastore\ObjectDatabaseFixture.cs" />

@ -1,42 +1,10 @@
using System;
using System.Linq;
using Marr.Data.Converters;
using Marr.Data.Mapping;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Datastore.Converters
{
public class ProviderSettingConverter : EmbeddedDocumentConverter
{
public override object FromDB(ConverterContext context)
{
if (context.DbValue == DBNull.Value)
{
return DBNull.Value;
}
var stringValue = (string)context.DbValue;
if (string.IsNullOrWhiteSpace(stringValue))
{
return null;
}
var ordinal = context.DataRecord.GetOrdinal("ConfigContract");
var implementation = context.DataRecord.GetString(ordinal);
var impType = typeof(IProviderConfig).Assembly.GetTypes().Single(c => c.Name == implementation);
return Json.Deserialize(stringValue, impType);
}
}
public class EmbeddedDocumentConverter : IConverter
{
public virtual object FromDB(ConverterContext context)

@ -0,0 +1,36 @@
using System;
using Marr.Data.Converters;
using NzbDrone.Common.Reflection;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Datastore.Converters
{
public class ProviderSettingConverter : EmbeddedDocumentConverter
{
public override object FromDB(ConverterContext context)
{
if (context.DbValue == DBNull.Value)
{
return NullConfig.Instance;
}
var stringValue = (string)context.DbValue;
if (string.IsNullOrWhiteSpace(stringValue))
{
return NullConfig.Instance;
}
var ordinal = context.DataRecord.GetOrdinal("ConfigContract");
var implementation = context.DataRecord.GetString(ordinal);
var impType = typeof (IProviderConfig).Assembly.FindTypeByName(implementation);
return Json.Deserialize(stringValue, impType);
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Data;
using FluentMigrator;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(23)]
public class add_config_contract_to_indexers : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Update.Table("Indexers").Set(new { ConfigContract = "NewznabSettings" }).Where(new { Implementation = "Newznab" });
Update.Table("Indexers").Set(new { ConfigContract = "OmgwtfnzbsSettings" }).Where(new { Implementation = "Omgwtfnzbs" });
Update.Table("Indexers").Set(new { ConfigContract = "NullConfig" }).Where(new { Implementation = "Wombles" });
Update.Table("Indexers").Set(new { ConfigContract = "NullConfig" }).Where(new { Implementation = "Eztv" });
Delete.FromTable("Indexers").IsNull("ConfigContract");
}
}
}

@ -10,7 +10,7 @@ namespace NzbDrone.Core.Indexers
}
public class IndexerService : ProviderFactory<IIndexer, IndexerDefinition>
public class IndexerService : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerService
{
private readonly IIndexerRepository _providerRepository;
private readonly IEnumerable<IIndexer> _providers;

@ -140,6 +140,7 @@
<Compile Include="DataAugmentation\Xem\XemService.cs" />
<Compile Include="Datastore\ConnectionStringFactory.cs" />
<Compile Include="Datastore\Converters\BooleanIntConverter.cs" />
<Compile Include="Datastore\Converters\ProviderSettingConverter.cs" />
<Compile Include="Datastore\Converters\QualityIntConverter.cs" />
<Compile Include="Datastore\Converters\Int32Converter.cs" />
<Compile Include="Datastore\Converters\EmbeddedDocumentConverter.cs" />
@ -172,6 +173,7 @@
<Compile Include="Datastore\Migration\020_add_year_and_seasons_to_series.cs" />
<Compile Include="Datastore\Migration\021_drop_seasons_table.cs" />
<Compile Include="Datastore\Migration\022_move_notification_to_generic_provider.cs" />
<Compile Include="Datastore\Migration\023_add_config_contract_to_indexers.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />

@ -38,23 +38,28 @@ namespace NzbDrone.Core.ThingiProvider
public abstract class ProviderDefinition : ModelBase
{
private IProviderConfig _settings;
public string Name { get; set; }
public string Implementation { get; set; }
public bool Enable { get; set; }
public string ConfigContract
public string ConfigContract { get; set; }
public IProviderConfig Settings
{
get
{
if (Settings == null) return null;
return Settings.GetType().Name;
return _settings;
}
set
{
_settings = value;
if (value != null)
{
ConfigContract = value.GetType().Name;
}
}
}
public IProviderConfig Settings { get; set; }
}
public interface IProviderConfig

@ -14,7 +14,6 @@ namespace NzbDrone.Core.ThingiProvider
List<TProviderDefinition> All();
List<TProvider> GetAvailableProviders();
TProviderDefinition Get(int id);
//List<TProvider> Schema();
TProviderDefinition Create(TProviderDefinition indexer);
void Update(TProviderDefinition indexer);
void Delete(int id);
@ -52,22 +51,6 @@ namespace NzbDrone.Core.ThingiProvider
return _providerRepository.Get(id);
}
/* public List<TProvider> Schema()
{
var indexers = new List<Indexer>();
var newznab = new Indexer();
newznab.Instance = new Newznab.Newznab();
newznab.Id = 1;
newznab.Name = "Newznab";
newznab.Settings = new NewznabSettings();
newznab.Implementation = "Newznab";
indexers.Add(newznab);
return indexers;
}*/
public TProviderDefinition Create(TProviderDefinition provider)
{
return _providerRepository.Insert(provider);
@ -113,10 +96,10 @@ namespace NzbDrone.Core.ThingiProvider
{
var storedProvider = _providerRepository.All();
foreach (var providerDefinition in storedProvider.Where(i => GetImplementation(i) == null))
foreach (var invalidDefinition in storedProvider.Where(def => GetImplementation(def) == null))
{
_logger.Debug("Removing {0} ", providerDefinition.Name);
_providerRepository.Delete(providerDefinition);
_logger.Debug("Removing {0} ", invalidDefinition.Name);
_providerRepository.Delete(invalidDefinition);
}
}
}

Loading…
Cancel
Save