Skip to content

Commit

Permalink
Add InMemory Snoozle implementation and cleanup
Browse files Browse the repository at this point in the history
- The HttpVerbs parameter for the custom computation is no longer optional
- PropertyConfigurationsForWrite has been split into Create/Update
  • Loading branch information
CharlieJKendall committed Mar 3, 2020
1 parent 99470f9 commit 349a0e7
Show file tree
Hide file tree
Showing 39 changed files with 837 additions and 51 deletions.
9 changes: 9 additions & 0 deletions src/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@ dotnet_diagnostic.CA1308.severity = none

# CA1304: Specify CultureInfo
dotnet_diagnostic.CA1304.severity = none

# CA1812: Internal class that is apparently never instantiated
dotnet_diagnostic.CA1812.severity = none

# CA1305: Specify IFormatProvider
dotnet_diagnostic.CA1305.severity = none

# CA1031: Do not catch general exception types
dotnet_diagnostic.CA1031.severity = none
6 changes: 6 additions & 0 deletions src/Snoozle.InMemory/Configuration/InMemoryConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Snoozle.InMemory.Configuration
{
public class InMemoryConfiguration
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public interface IInMemoryModelConfiguration : IModelConfiguration
{
string JsonFilePath { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public interface IInMemoryPropertyConfiguration : IPropertyConfiguration
{
int GetNextPrimaryKeyValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public interface IInMemoryResourceConfiguration : IResourceConfiguration<IInMemoryPropertyConfiguration, IInMemoryModelConfiguration>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Snoozle.Abstractions;
using System.Collections.Generic;

namespace Snoozle.InMemory.Implementation
{
public interface IInMemoryRuntimeConfiguration<out TResource> : IRuntimeConfiguration
where TResource : class, IRestResource
{
TResource GetEntryByPrimaryKey(string primaryKey);

IEnumerable<TResource> GetAllEntries();

TResource InsertEntry(object resource);

TResource UpdateEntry(object resource, string primaryKey);

bool DeleteEntry(string primaryKey);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public interface IInMemoryRuntimeConfigurationProvider : IRuntimeConfigurationProvider<IInMemoryRuntimeConfiguration<IRestResource>>
{
}
}
62 changes: 62 additions & 0 deletions src/Snoozle.InMemory/Implementation/InMemoryDataProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Snoozle.Abstractions;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Snoozle.InMemory.Implementation
{
internal class InMemoryDataProvider : IDataProvider
{
private readonly IInMemoryRuntimeConfigurationProvider _inMemoryRuntimeConfigurationProvider;

public InMemoryDataProvider(IInMemoryRuntimeConfigurationProvider inMemoryRuntimeConfigurationProvider)
{
_inMemoryRuntimeConfigurationProvider = inMemoryRuntimeConfigurationProvider;
}

public Task<bool> DeleteByIdAsync<TResource>(object primaryKey)
where TResource : class, IRestResource
{
IInMemoryRuntimeConfiguration<TResource> config = GetConfig<TResource>();

return Task.FromResult(config.DeleteEntry(primaryKey.ToString()));
}

public Task<TResource> InsertAsync<TResource>(TResource resourceToCreate)
where TResource : class, IRestResource
{
IInMemoryRuntimeConfiguration<TResource> config = GetConfig<TResource>();

return Task.FromResult(config.InsertEntry(resourceToCreate));
}

public Task<IEnumerable<TResource>> SelectAllAsync<TResource>()
where TResource : class, IRestResource
{
IInMemoryRuntimeConfiguration<TResource> config = GetConfig<TResource>();

return Task.FromResult(config.GetAllEntries());
}

public Task<TResource> SelectByIdAsync<TResource>(object primaryKey)
where TResource : class, IRestResource
{
IInMemoryRuntimeConfiguration<TResource> config = GetConfig<TResource>();

return Task.FromResult(config.GetEntryByPrimaryKey(primaryKey.ToString()));
}

public Task<TResource> UpdateAsync<TResource>(TResource resourceToUpdate, object primaryKey)
where TResource : class, IRestResource
{
IInMemoryRuntimeConfiguration<TResource> config = GetConfig<TResource>();

return Task.FromResult(config.UpdateEntry(resourceToUpdate, primaryKey.ToString()));
}

private IInMemoryRuntimeConfiguration<TResource> GetConfig<TResource>()
where TResource : class, IRestResource
{
return (IInMemoryRuntimeConfiguration<TResource>)_inMemoryRuntimeConfigurationProvider.GetRuntimeConfigurationForType(typeof(TResource));
}
}
}
10 changes: 10 additions & 0 deletions src/Snoozle.InMemory/Implementation/InMemoryModelConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public class InMemoryModelConfiguration<TResource> : BaseModelConfiguration<TResource>, IInMemoryModelConfiguration
where TResource : class, IRestResource
{
public string JsonFilePath { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public class InMemoryModelConfigurationBuilder : BaseModelConfigurationBuilder<IInMemoryModelConfiguration>, IModelConfigurationBuilder<IInMemoryModelConfiguration>
{
public InMemoryModelConfigurationBuilder(IInMemoryModelConfiguration modelConfiguration)
: base(modelConfiguration)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Snoozle.Abstractions;
using System.Threading;

namespace Snoozle.InMemory.Implementation
{
public class InMemoryPropertyConfiguration : BasePropertyConfiguration, IInMemoryPropertyConfiguration
{
private int _currentPrimaryKeyValue;

public int GetNextPrimaryKeyValue()
{
return Interlocked.Increment(ref _currentPrimaryKeyValue);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Snoozle.Abstractions;

namespace Snoozle.InMemory.Implementation
{
public class InMemoryPropertyConfigurationBuilder<TResource, TProperty> : BasePropertyConfigurationBuilder<TResource, TProperty, IInMemoryPropertyConfiguration>, IPropertyConfigurationBuilder<TProperty, IInMemoryPropertyConfiguration>
where TResource : class, IRestResource
{
public InMemoryPropertyConfigurationBuilder(IInMemoryPropertyConfiguration propertyConfiguration)
: base(propertyConfiguration)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Snoozle.Abstractions;
using System.Collections.Generic;

namespace Snoozle.InMemory.Implementation
{
public class InMemoryResourceConfiguration<TResource> : BaseResourceConfiguration<TResource, IInMemoryPropertyConfiguration, IInMemoryModelConfiguration>, IInMemoryResourceConfiguration
where TResource : class, IRestResource
{
public InMemoryResourceConfiguration(
IInMemoryModelConfiguration modelConfiguration,
IEnumerable<IInMemoryPropertyConfiguration> propertyConfigurations)
: base(modelConfiguration, propertyConfigurations)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Snoozle.Abstractions;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace Snoozle.InMemory.Implementation
{
internal class InMemoryRuntimeConfiguration<TResource> : BaseRuntimeConfiguration<IInMemoryPropertyConfiguration, IInMemoryModelConfiguration, TResource>, IInMemoryRuntimeConfiguration<TResource>
where TResource : class, IRestResource
{
private readonly ConcurrentDictionary<string, TResource> _data;

// This is created by reflection, so be careful when changing/adding parameters
public InMemoryRuntimeConfiguration(IInMemoryResourceConfiguration resourceConfiguration, List<TResource> initialData)
: base(resourceConfiguration)
{
initialData = initialData ?? new List<TResource>();
_data = new ConcurrentDictionary<string, TResource>(initialData?.ToDictionary(x => GetPrimaryKeyValue(x).ToString()));
PropertyConfigurationBuilderExtensions.SetGlobalPrimaryKeyInteger(GetMaxPrimaryKeyIntegerValueOrDefault());
}

private int GetMaxPrimaryKeyIntegerValueOrDefault()
{
try
{
return _data.Keys.Select(x => int.Parse(x)).Max();
}
catch
{
return default;
}
}

public bool DeleteEntry(string primaryKey)
{
_data.TryRemove(primaryKey, out TResource resourceRemoved);

return resourceRemoved != default;
}

public IEnumerable<TResource> GetAllEntries()
{
return _data.Values.AsEnumerable();
}

public TResource GetEntryByPrimaryKey(string primaryKey)
{
return _data.GetValueOrDefault(primaryKey);
}

public TResource InsertEntry(object resource)
{
TResource typedResource = (TResource)resource;
object primaryKey = GetPrimaryKeyValue(typedResource);

return _data.TryAdd(primaryKey.ToString(), typedResource) ? typedResource : default;
}

public TResource UpdateEntry(object resource, string primaryKey)
{
TResource typedResource = (TResource)resource;

// If we are not able to retrieve the current value and update it to the new value, return the default value
return _data.TryGetValue(primaryKey, out TResource existingResource) && _data.TryUpdate(primaryKey, typedResource, existingResource)
? typedResource
: default;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Snoozle.Abstractions;
using System;
using System.Collections.Generic;

namespace Snoozle.InMemory.Implementation
{
internal class InMemoryRuntimeConfigurationProvider : BaseRuntimeConfigurationProvider<IInMemoryRuntimeConfiguration<IRestResource>>, IInMemoryRuntimeConfigurationProvider
{
public InMemoryRuntimeConfigurationProvider(Dictionary<Type, IInMemoryRuntimeConfiguration<IRestResource>> runtimeConfigurations)
: base(runtimeConfigurations)
{
}
}
}
51 changes: 51 additions & 0 deletions src/Snoozle.InMemory/InMemoryResourceConfigurationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Snoozle.Abstractions;
using Snoozle.Exceptions;
using Snoozle.InMemory.Implementation;
using System.Linq;

namespace Snoozle.InMemory
{
public abstract class InMemoryResourceConfigurationBuilder<TResource> : BaseResourceConfigurationBuilder<TResource, IInMemoryPropertyConfiguration, IInMemoryResourceConfiguration, IInMemoryModelConfiguration>
where TResource : class, IRestResource
{
protected override IPropertyConfigurationBuilder<TProperty, IInMemoryPropertyConfiguration> CreatePropertyConfigurationBuilder<TProperty>(
IInMemoryPropertyConfiguration propertyConfiguration)
{
return new InMemoryPropertyConfigurationBuilder<TResource, TProperty>(propertyConfiguration);
}

protected override IInMemoryResourceConfiguration CreateResourceConfiguration()
{
return new InMemoryResourceConfiguration<TResource>(ModelConfiguration, PropertyConfigurations);
}

protected override IInMemoryModelConfiguration CreateModelConfiguration()
{
return new InMemoryModelConfiguration<TResource>();
}

protected override IInMemoryPropertyConfiguration CreatePropertyConfiguration()
{
return new InMemoryPropertyConfiguration();
}

protected override IModelConfigurationBuilder<IInMemoryModelConfiguration> CreateModelConfigurationBuilder()
{
return new InMemoryModelConfigurationBuilder(ModelConfiguration);
}

protected override void SetPropertyConfigurationDefaults()
{
base.SetPropertyConfigurationDefaults();
}

protected override void ValidateFinal()
{
base.ValidateFinal();

ExceptionHelper.InvalidOperation.ThrowIfTrue(
PropertyConfigurations.Single(prop => prop.IsPrimaryResourceIdentifier).ValueComputationFunc == null,
$"The primary identifier for {typeof(TResource).Name} must have a unique value computation function defined for it (e.g. () => Guid.NewGuid()).");
}
}
}
Loading

0 comments on commit 349a0e7

Please sign in to comment.