Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
next-version: 1.0.6
next-version: 2.0.0
tag-prefix: '[vV]'
mode: ContinuousDeployment
branches:
Expand Down
14 changes: 14 additions & 0 deletions Ninja.FeatureOne.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureOne", "src\FeatureOn
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureOne.Tests", "test\FeatureOne.Tests\FeatureOne.Tests.csproj", "{F51B62E7-1A8F-41DC-B027-074932A01D33}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeatureOne.SQL", "src\FeatureOne.SQL\FeatureOne.SQL.csproj", "{FED48C4A-1EEC-491C-8F5D-886763DF9388}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeatureOne.SQL.Tests", "test\FeatureOne.SQL.Tests\FeatureOne.SQL.Tests.csproj", "{A6102616-CA8C-4C7F-AF16-C8F451E6D62D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,6 +43,14 @@ Global
{F51B62E7-1A8F-41DC-B027-074932A01D33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F51B62E7-1A8F-41DC-B027-074932A01D33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F51B62E7-1A8F-41DC-B027-074932A01D33}.Release|Any CPU.Build.0 = Release|Any CPU
{FED48C4A-1EEC-491C-8F5D-886763DF9388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FED48C4A-1EEC-491C-8F5D-886763DF9388}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FED48C4A-1EEC-491C-8F5D-886763DF9388}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FED48C4A-1EEC-491C-8F5D-886763DF9388}.Release|Any CPU.Build.0 = Release|Any CPU
{A6102616-CA8C-4C7F-AF16-C8F451E6D62D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6102616-CA8C-4C7F-AF16-C8F451E6D62D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6102616-CA8C-4C7F-AF16-C8F451E6D62D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6102616-CA8C-4C7F-AF16-C8F451E6D62D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -47,6 +59,8 @@ Global
{FB8FCDD0-A3D4-4776-85E0-C47ECFB3D310} = {9930EAFC-568F-4676-82AB-2B8F9D7535B3}
{65BD1F94-CEF4-4CC1-8482-3FF72BBF620F} = {B5EFC87D-E5C5-488E-AA89-06D26027E4C7}
{F51B62E7-1A8F-41DC-B027-074932A01D33} = {E864826B-B5D2-4DAD-B53A-2A3976226B53}
{FED48C4A-1EEC-491C-8F5D-886763DF9388} = {B5EFC87D-E5C5-488E-AA89-06D26027E4C7}
{A6102616-CA8C-4C7F-AF16-C8F451E6D62D} = {E864826B-B5D2-4DAD-B53A-2A3976226B53}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {745CC402-145C-4E31-BAB7-DA93F8292512}
Expand Down
240 changes: 188 additions & 52 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
markdown: GFM
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using FeatureOne.Core;

namespace FeatureOne.Core.Stores
namespace FeatureOne.SQL
{
public static class ConditionFactory
internal class ConditionDeserializer : IConditionDeserializer
{
private static Type[] loaddedTypes;

Expand All @@ -17,32 +18,36 @@ private static Type[] LoaddedTypes
get
{
if (loaddedTypes == null || loaddedTypes.Length == 0)
loaddedTypes = Assembly.GetExecutingAssembly().GetTypes();
loaddedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
.Where(p => typeof(ICondition).IsAssignableFrom(p)).ToArray();

return loaddedTypes;
}
}

public static ICondition Create(JsonObject JsonObject)
public ICondition Deserialize(JsonObject condition)
{
if (JsonObject == null)
throw new ArgumentNullException(nameof(JsonObject));
if (condition == null)
throw new ArgumentNullException(nameof(condition));

var typeName = JsonObject?["type"]?.ToString();
var typeName = condition?["type"]?.ToString();

var toggle = CreateInstance(new NamePostFix(typeName, "Condition"));

HydrateToggle(toggle, JsonObject);
HydrateToggle(toggle, condition);

return toggle;
}

public static ICondition[] Create(JsonObject[] conditions)
private static ICondition CreateInstance(NamePostFix conditionName)
{
if (conditions == null)
throw new ArgumentNullException(nameof(conditions));
var type = LoaddedTypes
.FirstOrDefault(p => typeof(ICondition).IsAssignableFrom(p) && p.Name.Equals(conditionName.Name, StringComparison.OrdinalIgnoreCase));

return conditions.Select(s => Create(s)).ToArray();
if (type == null)
throw new Exception($"Could not find a toggle type for: '{conditionName.Name}'");

return (ICondition)Activator.CreateInstance(type, true);
}

private static void HydrateToggle(ICondition toggleCondition, JsonObject state)
Expand Down Expand Up @@ -75,16 +80,5 @@ private static PropertyInfo[] GetProperties(ICondition condition)

return propertyInfos;
}

private static ICondition CreateInstance(NamePostFix conditionName)
{
var type = LoaddedTypes
.FirstOrDefault(p => typeof(ICondition).IsAssignableFrom(p) && p.Name.Equals(conditionName.Name, StringComparison.OrdinalIgnoreCase));

if (type == null)
throw new Exception($"Could not find a toggle type for: '{conditionName.Name}'");

return (ICondition)Activator.CreateInstance(type, true);
}
}
}
8 changes: 8 additions & 0 deletions src/FeatureOne.SQL/DbRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace FeatureOne.SQL
{
public class DbRecord
{
public string Name { get; set; }
public string Toggle { get; set; }
}
}
13 changes: 13 additions & 0 deletions src/FeatureOne.SQL/FeatureCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Runtime.Caching;

namespace FeatureOne.SQL
{
internal class FeatureCache : ICache
{
public void Add(string key, object value, int expiry)
=> MemoryCache.Default.Add(key, value, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(expiry) });

public object Get(string key) => MemoryCache.Default.Get(key);
}
}
73 changes: 73 additions & 0 deletions src/FeatureOne.SQL/FeatureOne.SQL.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>disable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
<GeneratedAssemblyInfoFile>AssemblyInfo.cs</GeneratedAssemblyInfoFile>
<PackRelease>true</PackRelease>
<IsPackable>true</IsPackable>
<AssemblyName>FeatureOne.SQL</AssemblyName>
<RootNamespace>FeatureOne.SQL</RootNamespace>
<PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Title>FeatureOne.SQL</Title>
<Authors>ninja.shayk</Authors>
<Company>Ninja.Sha!4H</Company>
<Product>FeatureOne</Product>
<Description>.Net library to implement feature toggles with SQL backend.</Description>
<Copyright>Copyright (c) 2023 Ninja Sha!4h</Copyright>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/NinjaRocks/FeatureOne</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>feature-toggle; feature-flag; feature-flags; feature-toggles; .netstandard2.1; featureOne; SQL-Backend; SQL-Toggles; SQL</PackageTags>
<Version>2.0.0</Version>
<PackageLicenseFile>License.md</PackageLicenseFile>
<PackageIcon>ninja-icon-16.png</PackageIcon>
<PackageReleaseNotes>
Release Notes v2.0.0. - SQL Storage Provider
Core Functionality :-
Added support for SQL storage provider for Feature Toggle.
- Supports MSSQL, SQLite, ODBC, OLEDB, MySQL, PostgreSQL Db providers.
- Provides memory caching - enabled via configuration.
- Added extensibility for Custom implementations-
- Provides extension point to support more SQL providers.
- Provides extenion point for custom caching.
- Provides extension point for custom deserializer for Toggle Conditions.
</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<None Include="..\..\License.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\..\ninja-icon-16.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="System.Data.Common" Version="4.3.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="System.Data.Odbc" Version="7.0.0" />
<PackageReference Include="System.Data.OleDb" Version="7.0.0" />
<PackageReference Include="System.Data.SQLite" Version="1.0.86" />
<PackageReference Include="MySql.Data" Version="8.0.33" />
<PackageReference Include="System.Runtime.Caching " Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\FeatureOne\FeatureOne.csproj" />
</ItemGroup>

</Project>
20 changes: 20 additions & 0 deletions src/FeatureOne.SQL/ICache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace FeatureOne.SQL
{
public interface ICache
{
/// <summary>
/// Add item to cache
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
void Add(string key, object value, int expiry);

/// <summary>
/// Get item from cache
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
object Get(string key);
}
}
13 changes: 13 additions & 0 deletions src/FeatureOne.SQL/IConditionDeserializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Text.Json.Nodes;
using FeatureOne.Core;

namespace FeatureOne.SQL
{
/// <summary>
/// Implement to provide deserialization strategy of condition types.
/// </summary>
public interface IConditionDeserializer
{
ICondition Deserialize(JsonObject condition);
}
}
7 changes: 7 additions & 0 deletions src/FeatureOne.SQL/IDbRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FeatureOne.SQL
{
public interface IDbRepository
{
DbRecord[] GetByName(string name);
}
}
9 changes: 9 additions & 0 deletions src/FeatureOne.SQL/IToggleDeserializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using FeatureOne.Core;

namespace FeatureOne.SQL
{
public interface IToggleDeserializer
{
IToggle Deserialize(string toggle);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace FeatureOne.Core
namespace FeatureOne.SQL
{
public class NamePostFix
{
Expand Down
Loading