Skip to content

Commit adc3ff0

Browse files
committed
Added support for Sha256 hasing and Base64 conversion of RowKey
1 parent 67478eb commit adc3ff0

16 files changed

+220
-17
lines changed

CoreHelpers.WindowsAzure.Storage.Table.Abstractions/IStorageContext.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Linq;
55
using System.Reflection;
66
using System.Threading.Tasks;
7-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
87

98
namespace CoreHelpers.WindowsAzure.Storage.Table
109
{
@@ -27,6 +26,8 @@ public interface IStorageContext : IDisposable
2726

2827
void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, String tableName);
2928

29+
void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, nVirtualValueEncoding rowKeyEncoding, String tableName);
30+
3031
IStorageContext CreateChildContext();
3132

3233
IStorageContext EnableAutoCreateTable();

CoreHelpers.WindowsAzure.Storage.Table.Abstractions/IStorageContextQuery.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55

6-
namespace CoreHelpers.WindowsAzure.Storage.Table.Abstractions
6+
namespace CoreHelpers.WindowsAzure.Storage.Table
77
{
88
public interface IStorageContextQueryNow<T>
99
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
namespace CoreHelpers.WindowsAzure.Storage.Table
3+
{
4+
public enum nVirtualValueEncoding
5+
{
6+
None,
7+
Base64,
8+
Sha256
9+
}
10+
}
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;
3+
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;
4+
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Extensions;
5+
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Models;
6+
7+
namespace CoreHelpers.WindowsAzure.Storage.Table.Tests
8+
{
9+
[Storable(Tablename = "VirtualRowKeyNone")]
10+
[VirtualRowKey("{{RK}}")]
11+
public class VirtualRowKeyNone
12+
{
13+
[PartitionKey]
14+
public string PK { get; set; } = String.Empty;
15+
16+
public string RK { get; set; } = String.Empty;
17+
}
18+
19+
[Storable(Tablename = "VirtualRowKeyNone")]
20+
[VirtualRowKey("{{RK}}-{{RK2}}")]
21+
public class VirtualRowKeyCombinedNone: VirtualRowKeyNone
22+
{
23+
public string RK2 { get; set; } = String.Empty;
24+
}
25+
26+
[Storable(Tablename = "VirtualRowKeyNone")]
27+
[VirtualRowKey("{{RK}}", nVirtualValueEncoding.Base64)]
28+
public class VirtualRowKeyBase64 : VirtualRowKeyNone
29+
{}
30+
31+
[Storable(Tablename = "VirtualRowKeyNone")]
32+
[VirtualRowKey("{{RK}}", nVirtualValueEncoding.Sha256)]
33+
public class VirtualRowKeySha256: VirtualRowKeyNone
34+
{ }
35+
36+
public class ITS24VirtualRowKey
37+
{
38+
private readonly IStorageContext _rootContext;
39+
40+
public ITS24VirtualRowKey(IStorageContext context)
41+
{
42+
_rootContext = context;
43+
}
44+
45+
[Fact]
46+
public void VerifyVirtualRowKeyNoneEncoding()
47+
{
48+
using (var scp = _rootContext.CreateChildContext())
49+
{
50+
// set the tablename context
51+
scp.SetTableContext();
52+
53+
// configure the entity mapper
54+
scp.AddAttributeMapper<VirtualRowKeyNone>();
55+
56+
// check the entity
57+
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyNone>(new VirtualRowKeyNone() { PK = "P01", RK = "R01" }, scp);
58+
Assert.Equal("R01", entity.RowKey);
59+
}
60+
}
61+
62+
[Fact]
63+
public void VerifyVirtualRowKeyNoneEncodingCombined()
64+
{
65+
using (var scp = _rootContext.CreateChildContext())
66+
{
67+
// set the tablename context
68+
scp.SetTableContext();
69+
70+
// configure the entity mapper
71+
scp.AddAttributeMapper<VirtualRowKeyCombinedNone>();
72+
73+
// check the entity
74+
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyCombinedNone>(new VirtualRowKeyCombinedNone() { PK = "P01", RK = "R01", RK2 = "CMB" }, scp);
75+
Assert.Equal("R01-CMB", entity.RowKey);
76+
}
77+
}
78+
79+
[Fact]
80+
public void VerifyVirtualRowKeyBase64Encoding()
81+
{
82+
using (var scp = _rootContext.CreateChildContext())
83+
{
84+
// set the tablename context
85+
scp.SetTableContext();
86+
87+
// configure the entity mapper
88+
scp.AddAttributeMapper<VirtualRowKeyBase64>();
89+
90+
// check the entity
91+
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyBase64>(new VirtualRowKeyBase64() { PK = "P01", RK = "R01" }, scp);
92+
Assert.Equal("UjAx", entity.RowKey);
93+
}
94+
}
95+
96+
[Fact]
97+
public void VerifyVirtualRowKeySha256Encoding()
98+
{
99+
using (var scp = _rootContext.CreateChildContext())
100+
{
101+
// set the tablename context
102+
scp.SetTableContext();
103+
104+
// configure the entity mapper
105+
scp.AddAttributeMapper<VirtualRowKeySha256>();
106+
107+
// check the entity
108+
var entity = TableEntityDynamic.ToEntity<VirtualRowKeySha256>(new VirtualRowKeySha256() { PK = "P01", RK = "R01" }, scp);
109+
Assert.Equal("e0a64b0b6d837fa4edc328ab9ddea0e3e7e0e4f715304c1d6bf3d0adc9d5292a", entity.RowKey);
110+
}
111+
}
112+
}
113+
}

CoreHelpers.WindowsAzure.Storage.Table/AssemblyInfo.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Reflection;
3+
using System.Runtime.CompilerServices;
34

45
[assembly: AssemblyCompany("Core Helpers")]
56
[assembly: AssemblyProduct("WindowsAzure.Storage.Table")]
@@ -12,4 +13,6 @@
1213
[assembly: AssemblyConfiguration("Debug")]
1314
#else
1415
[assembly: AssemblyConfiguration("Release")]
15-
#endif
16+
#endif
17+
18+
[assembly: InternalsVisibleTo("CoreHelpers.WindowsAzure.Storage.Table.Tests")]
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
using System;
2+
using CoreHelpers.WindowsAzure.Storage.Table;
23

34
namespace CoreHelpers.WindowsAzure.Storage.Table.Attributes
4-
{
5+
{
56
[AttributeUsage(AttributeTargets.Class)]
67
public class VirtualRowKeyAttribute : Attribute
78
{
89
public string RowKeyFormat { get; set; }
9-
10-
public VirtualRowKeyAttribute(string RowKeyFormat) {
10+
11+
public nVirtualValueEncoding Encoding { get; set; }
12+
13+
public VirtualRowKeyAttribute(string RowKeyFormat, nVirtualValueEncoding Encoding = nVirtualValueEncoding.None) {
1114
this.RowKeyFormat = RowKeyFormat;
15+
this.Encoding = Encoding;
1216
}
1317
}
1418
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace CoreHelpers.WindowsAzure.Storage.Table.Extensions
5+
{
6+
public static class StringExternsions
7+
{
8+
public static string ToBase64(this string plainText)
9+
{
10+
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
11+
return System.Convert.ToBase64String(plainTextBytes);
12+
}
13+
14+
public static string ToSha256(this string value)
15+
{
16+
// convert the string
17+
byte[] toBytes = Encoding.ASCII.GetBytes(value);
18+
19+
// generate the SHA1 key
20+
var sha256 = global::System.Security.Cryptography.SHA256.Create();
21+
var hash = sha256.ComputeHash(toBytes);
22+
23+
// done
24+
return GenerateHexStringFromBytes(hash);
25+
}
26+
27+
private static string GenerateHexStringFromBytes(byte[] bytes)
28+
{
29+
var sb = new StringBuilder();
30+
foreach (byte b in bytes)
31+
{
32+
var hex = b.ToString("x2");
33+
sb.Append(hex);
34+
}
35+
return sb.ToString();
36+
}
37+
}
38+
}
39+

CoreHelpers.WindowsAzure.Storage.Table/Internal/StorageContextQueryNow.cs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99
using Azure.Data.Tables;
10-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
1110
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;
1211

1312
namespace CoreHelpers.WindowsAzure.Storage.Table.Internal

CoreHelpers.WindowsAzure.Storage.Table/Internal/StorageContextQueryWithFilter.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
43
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;
54

65
namespace CoreHelpers.WindowsAzure.Storage.Table.Internal

CoreHelpers.WindowsAzure.Storage.Table/Internal/StorageContextQueryWithPartitionKey.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
32

43
namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
54
{

CoreHelpers.WindowsAzure.Storage.Table/Internal/StorageContextQueryWithRowKey.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
32

43
namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
54
{

CoreHelpers.WindowsAzure.Storage.Table/Serialization/TableEntityBuilder.cs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using Azure.Data.Tables;
4+
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;
5+
using CoreHelpers.WindowsAzure.Storage.Table.Extensions;
46

57
namespace CoreHelpers.WindowsAzure.Storage.Table.Serialization
68
{
@@ -15,9 +17,22 @@ public TableEntityBuilder AddPartitionKey(string pkey)
1517
return this;
1618
}
1719

18-
public TableEntityBuilder AddRowKey(string rkey)
20+
public TableEntityBuilder AddRowKey(string rkey, nVirtualValueEncoding encoding = nVirtualValueEncoding.None)
1921
{
20-
_data.Add("RowKey", rkey);
22+
23+
switch (encoding)
24+
{
25+
case nVirtualValueEncoding.None:
26+
_data.Add("RowKey", rkey);
27+
break;
28+
case nVirtualValueEncoding.Base64:
29+
_data.Add("RowKey", rkey.ToBase64());
30+
break;
31+
case nVirtualValueEncoding.Sha256:
32+
_data.Add("RowKey", rkey.ToSha256());
33+
break;
34+
}
35+
2136
return this;
2237
}
2338

CoreHelpers.WindowsAzure.Storage.Table/Serialization/TableEntityDynamic.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@
1212
namespace CoreHelpers.WindowsAzure.Storage.Table.Serialization
1313
{
1414
internal static class TableEntityDynamic
15-
{
15+
{
16+
public static TableEntity ToEntity<T>(T model, IStorageContext context) where T : new()
17+
{
18+
if (context as StorageContext == null)
19+
throw new Exception("Invalid interface implemnetation");
20+
else
21+
return TableEntityDynamic.ToEntity<T>(model, (context as StorageContext).GetEntityMapper<T>());
22+
}
23+
1624
public static TableEntity ToEntity<T>(T model, StorageEntityMapper entityMapper) where T: new()
1725
{
1826
var builder = new TableEntityBuilder();
1927

2028
// set the keys
2129
builder.AddPartitionKey(GetTableStorageDefaultProperty<string, T>(entityMapper.PartitionKeyFormat, model));
22-
builder.AddRowKey(GetTableStorageDefaultProperty<string, T>(entityMapper.RowKeyFormat, model));
30+
builder.AddRowKey(GetTableStorageDefaultProperty<string, T>(entityMapper.RowKeyFormat, model), entityMapper.RowKeyEncoding);
2331

2432
// get all properties from model
2533
IEnumerable<PropertyInfo> objectProperties = model.GetType().GetTypeInfo().GetProperties();

CoreHelpers.WindowsAzure.Storage.Table/StoargeEntityMapper.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System;
2+
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;
23

34
namespace CoreHelpers.WindowsAzure.Storage.Table
45
{
56
public class StorageEntityMapper
67
{
78
public String PartitionKeyFormat { get; set; }
89
public String RowKeyFormat { get; set; }
9-
public String TableName { get; set; }
10+
public nVirtualValueEncoding RowKeyEncoding { get; set; }
11+
public String TableName { get; set; }
1012

1113
public StorageEntityMapper()
1214
{}
@@ -15,6 +17,7 @@ public StorageEntityMapper(StorageEntityMapper src)
1517
{
1618
this.PartitionKeyFormat = src.PartitionKeyFormat;
1719
this.RowKeyFormat = src.RowKeyFormat;
20+
this.RowKeyEncoding = src.RowKeyEncoding;
1821
this.TableName = src.TableName;
1922
}
2023
}

CoreHelpers.WindowsAzure.Storage.Table/StorageContextAttributeMapping.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ public void AddEntityMapper(Type entityType, StorageEntityMapper entityMapper)
1414
=> _entityMapperRegistry.Add(entityType, entityMapper);
1515

1616
public void AddEntityMapper(Type entityType, string partitionKeyFormat, string rowKeyFormat, string tableName)
17+
{
18+
AddEntityMapper(entityType, partitionKeyFormat, rowKeyFormat, nVirtualValueEncoding.None, tableName);
19+
}
20+
21+
public void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, nVirtualValueEncoding rowKeyEncoding, String tableName)
1722
{
1823
_entityMapperRegistry.Add(entityType, new StorageEntityMapper()
1924
{
2025
PartitionKeyFormat = partitionKeyFormat,
2126
RowKeyFormat = rowKeyFormat,
27+
RowKeyEncoding = rowKeyEncoding,
2228
TableName = tableName
2329
});
2430
}
@@ -66,6 +72,7 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
6672
// store the neded properties
6773
string partitionKeyFormat = null;
6874
string rowKeyFormat = null;
75+
var rowKeyEncoding = nVirtualValueEncoding.None;
6976

7077
// get the partitionkey property & rowkey property
7178
var properties = type.GetRuntimeProperties();
@@ -91,6 +98,9 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
9198
if (virtualRowKeyAttribute != null && !String.IsNullOrEmpty(virtualRowKeyAttribute.RowKeyFormat))
9299
rowKeyFormat = virtualRowKeyAttribute.RowKeyFormat;
93100

101+
if (virtualRowKeyAttribute != null && virtualRowKeyAttribute.Encoding != nVirtualValueEncoding.None)
102+
rowKeyEncoding = virtualRowKeyAttribute.Encoding;
103+
94104
// check
95105
if (partitionKeyFormat == null || rowKeyFormat == null)
96106
throw new Exception("Missing Partition or RowKey Attribute");
@@ -100,7 +110,8 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
100110
{
101111
TableName = String.IsNullOrEmpty(optionalTablenameOverride) ? storableAttribute.Tablename : optionalTablenameOverride,
102112
PartitionKeyFormat = partitionKeyFormat,
103-
RowKeyFormat = rowKeyFormat
113+
RowKeyFormat = rowKeyFormat,
114+
RowKeyEncoding = rowKeyEncoding
104115
});
105116
}
106117

CoreHelpers.WindowsAzure.Storage.Table/StorageContextQueryEntities.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading.Tasks;
5-
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
65
using CoreHelpers.WindowsAzure.Storage.Table.Internal;
76

87
namespace CoreHelpers.WindowsAzure.Storage.Table

0 commit comments

Comments
 (0)