Commit 94dfd9b1 authored by Marc Gravell's avatar Marc Gravell

Merge pull request #92 from mwikstrom/master

Key space isolation extension to IDatabase
parents 651c5604 92765c7c
...@@ -155,6 +155,11 @@ ...@@ -155,6 +155,11 @@
<Compile Include="StackExchange\Redis\When.cs" /> <Compile Include="StackExchange\Redis\When.cs" />
<Compile Include="StackExchange\Redis\ShutdownMode.cs" /> <Compile Include="StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="StackExchange\Redis\SaveType.cs" /> <Compile Include="StackExchange\Redis\SaveType.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" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="StackExchange\Redis\SocketManager.Poll.cs"> <Compile Include="StackExchange\Redis\SocketManager.Poll.cs">
......
...@@ -149,6 +149,11 @@ ...@@ -149,6 +149,11 @@
<Compile Include="StackExchange\Redis\When.cs" /> <Compile Include="StackExchange\Redis\When.cs" />
<Compile Include="StackExchange\Redis\ShutdownMode.cs" /> <Compile Include="StackExchange\Redis\ShutdownMode.cs" />
<Compile Include="StackExchange\Redis\SaveType.cs" /> <Compile Include="StackExchange\Redis\SaveType.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" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="StackExchange\Redis\SocketManager.Poll.cs"> <Compile Include="StackExchange\Redis\SocketManager.Poll.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();
}
}
}
...@@ -151,6 +151,11 @@ ...@@ -151,6 +151,11 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
......
...@@ -145,6 +145,11 @@ ...@@ -145,6 +145,11 @@
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\StringSplits.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\TaskSource.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" /> <Compile Include="..\StackExchange.Redis\StackExchange\Redis\When.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\BatchWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseExtension.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\DatabaseWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\TransactionWrapper.cs" />
<Compile Include="..\StackExchange.Redis\StackExchange\Redis\KeyspaceIsolation\WrapperBase.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
......
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