Commit ae13b6d0 authored by mwikstrom's avatar mwikstrom

Added keyspace isolation extension

parent 651c5604
...@@ -67,6 +67,11 @@ ...@@ -67,6 +67,11 @@
<Compile Include="StackExchange\Redis\ExtensionMethods.cs" /> <Compile Include="StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="StackExchange\Redis\HashEntry.cs" /> <Compile Include="StackExchange\Redis\HashEntry.cs" />
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" /> <Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
<Compile Include="StackExchange\Redis\MigrateOptions.cs" /> <Compile Include="StackExchange\Redis\MigrateOptions.cs" />
<Compile Include="StackExchange\Redis\RedisChannel.cs" /> <Compile Include="StackExchange\Redis\RedisChannel.cs" />
<Compile Include="StackExchange\Redis\Bitwise.cs" /> <Compile Include="StackExchange\Redis\Bitwise.cs" />
......
...@@ -144,11 +144,11 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -144,11 +144,11 @@ internal override void WriteImpl(PhysicalConnection physical)
internal class ExistsCondition : Condition internal class ExistsCondition : Condition
{ {
readonly bool expectedResult; internal readonly bool expectedResult;
readonly RedisValue hashField; internal readonly RedisValue hashField;
readonly RedisKey key; internal readonly RedisKey key;
public ExistsCondition(RedisKey key, RedisValue hashField, bool expectedResult) public ExistsCondition(RedisKey key, RedisValue hashField, bool expectedResult)
{ {
...@@ -197,11 +197,11 @@ internal override bool TryValidate(RawResult result, out bool value) ...@@ -197,11 +197,11 @@ internal override bool TryValidate(RawResult result, out bool value)
} }
} }
private class EqualsCondition : Condition internal class EqualsCondition : Condition
{ {
readonly bool expectedEqual; internal readonly bool expectedEqual;
readonly RedisValue hashField, expectedValue; internal readonly RedisValue hashField, expectedValue;
readonly RedisKey key; internal readonly RedisKey key;
public EqualsCondition(RedisKey key, RedisValue hashField, bool expectedEqual, RedisValue expectedValue) public EqualsCondition(RedisKey key, RedisValue hashField, bool expectedEqual, RedisValue expectedValue)
{ {
if (key.IsNull) throw new ArgumentException("key"); if (key.IsNull) throw new ArgumentException("key");
......
using System;
namespace StackExchange.Redis.StackExchange.Redis.KeyspaceIsolation
{
internal sealed class BatchWrapper : WrapperBase<IBatch>, IBatch
{
public BatchWrapper(IBatch inner, RedisKey prefix)
: base(inner, prefix)
{
}
public void Execute()
{
this.Inner.Execute();
}
}
}
using System;
namespace StackExchange.Redis.StackExchange.Redis.KeyspaceIsolation
{
/// <summary>
/// Provides the <see cref="WithKeyPrefix"/> extension method to <see cref="IDatabase"/>.
/// </summary>
public static class DatabaseExtension
{
/// <summary>
/// Creates a new <see cref="IDatabase"/> instance that provides an isolated key space
/// of the specified underyling database instance.
/// </summary>
/// <param name="database">
/// The underlying database instance that the returned instance shall use.
/// </param>
/// <param name="keyPrefix">
/// The prefix that defines a key space isolation for the returned database instance.
/// </param>
/// <returns>
/// A new <see cref="IDatabase"/> instance that invokes the specified underlying
/// <paramref name="database"/> but prepends the specified <paramref name="keyPrefix"/>
/// to all key paramters and thus forms a logical key space isolation.
/// </returns>
/// <remarks>
/// <para>
/// The following methods are not supported in a key space isolated database and
/// will throw an <see cref="NotSupportedException"/> when invoked:
/// </para>
/// <list type="bullet">
/// <item><see cref="IDatabaseAsync.KeyRandomAsync(CommandFlags)"/></item>
/// <item><see cref="IDatabase.KeyRandom(CommandFlags)"/></item>
/// </list>
/// <para>
/// Please notice that keys passed to a script are prefixed (as normal) but care must
/// be taken when a script returns the name of a key as that will (currently) not be
/// "unprefixed".
/// </para>
/// </remarks>
public static IDatabase WithKeyPrefix(this IDatabase database, RedisKey keyPrefix)
{
if (database == null)
{
throw new ArgumentNullException("database");
}
if (keyPrefix.IsNull || keyPrefix.Value.Length == 0)
{
throw new ArgumentException("The specified prefix cannot be null or empty", "keyPrefix");
}
return new DatabaseWrapper(database, keyPrefix);
}
}
}
using System;
using System.Threading.Tasks;
namespace StackExchange.Redis.StackExchange.Redis.KeyspaceIsolation
{
internal sealed class TransactionWrapper : WrapperBase<ITransaction>, ITransaction
{
public TransactionWrapper(ITransaction inner, RedisKey prefix)
: base(inner, prefix)
{
}
public ConditionResult AddCondition(Condition condition)
{
return this.Inner.AddCondition(this.ToInner(condition));
}
public bool Execute(CommandFlags flags = CommandFlags.None)
{
return this.Inner.Execute(flags);
}
public Task<bool> ExecuteAsync(CommandFlags flags = CommandFlags.None)
{
return this.Inner.ExecuteAsync(flags);
}
public void Execute()
{
this.Inner.Execute();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment