Skip to content

Feature: Implement direct storage of enums #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
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
59 changes: 59 additions & 0 deletions CoreHelpers.WindowsAzure.Storage.Table.Tests/ITS025StoreEnum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Contracts;
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Extensions;
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Models;
using Xunit.DependencyInjection;

namespace CoreHelpers.WindowsAzure.Storage.Table.Tests
{
[Startup(typeof(Startup))]
[Collection("Sequential")]
public class ITS025StoreEnum
{
private readonly IStorageContext _rootContext;

public ITS025StoreEnum(IStorageContext context)
{
_rootContext = context;
}

[Fact]
public async Task VerifyAttributeMapper()
{
using (var storageContext = _rootContext.CreateChildContext())
{
// set the tablename context
storageContext.SetTableContext();

// create a new user
var user = new UserModel4() { FirstName = "Egon", LastName = "Mueller", Contact = "[email protected]", UserType = UserTypeEnum.Pro };

// ensure we are using the attributes
storageContext.AddAttributeMapper();

// ensure the table exists
await storageContext.CreateTableAsync<UserModel4>();

// inser the model
await storageContext.MergeOrInsertAsync<UserModel4>(user);

// query all
var result = await storageContext.QueryAsync<UserModel4>();
Assert.Single(result);
Assert.Equal("Egon", result.First().FirstName);
Assert.Equal("Mueller", result.First().LastName);
Assert.Equal("[email protected]", result.First().Contact);
Assert.Equal(UserTypeEnum.Pro, result.First().UserType);

// Clean up
await storageContext.DeleteAsync<UserModel4>(result);
result = await storageContext.QueryAsync<UserModel4>();
Assert.NotNull(result);
Assert.Empty(result);

await storageContext.DropTableAsync<UserModel4>();
}
}
}
}

28 changes: 28 additions & 0 deletions CoreHelpers.WindowsAzure.Storage.Table.Tests/Models/UserModel4.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;

namespace CoreHelpers.WindowsAzure.Storage.Table.Tests.Models
{

public enum UserTypeEnum
{
Free,
Pro
}

[Storable()]
public class UserModel4
{
[PartitionKey]
public string P { get; set; } = "Partition01";

[RowKey]
public string Contact { get; set; } = String.Empty;

public string FirstName { get; set; } = String.Empty;
public string LastName { get; set; } = String.Empty;

public UserTypeEnum UserType { get; set; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@ private void InitializePageEnumeratorIfNeeded()

// evaluate the maxItems
int? maxPerPage = _context.maxPerPage.HasValue && _context.maxPerPage.Value > 0 ? _context.maxPerPage : null;


// fix Azurite bug
var filter = string.IsNullOrWhiteSpace(_context.filter) ? null : _context.filter;
// start the query
_pageEnumerator = tc.Query<TableEntity>(_context.filter, maxPerPage, _context.select, _context.cancellationToken).AsPages().GetEnumerator();
_pageEnumerator = tc.Query<TableEntity>(filter, maxPerPage, _context.select, _context.cancellationToken).AsPages().GetEnumerator();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ internal static class TableEntityDynamic
{
if (context as StorageContext == null)
throw new Exception("Invalid interface implemnetation");
else
else
return TableEntityDynamic.ToEntity<T>(model, (context as StorageContext).GetEntityMapper<T>());
}

public static TableEntity ToEntity<T>(T model, StorageEntityMapper entityMapper) where T: new()
public static TableEntity ToEntity<T>(T model, StorageEntityMapper entityMapper) where T : new()
{
var builder = new TableEntityBuilder();

Expand All @@ -42,11 +42,13 @@ internal static class TableEntityDynamic
// properties with the correct converter
var virtualTypeAttribute = property.GetCustomAttributes().Where(a => a is IVirtualTypeAttribute).Select(a => a as IVirtualTypeAttribute).FirstOrDefault<IVirtualTypeAttribute>();
if (virtualTypeAttribute != null)
virtualTypeAttribute.WriteProperty<T>(property, model, builder);
virtualTypeAttribute.WriteProperty<T>(property, model, builder);
else if (property.PropertyType.IsEnum)
builder.AddProperty(property.Name, property.GetValue(model, null).ToString());
else
builder.AddProperty(property.Name, property.GetValue(model, null));
builder.AddProperty(property.Name, property.GetValue(model, null));
}

// build the result
return builder.Build();
}
Expand All @@ -58,13 +60,13 @@ internal static class TableEntityDynamic

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

// visit all properties
foreach (PropertyInfo property in objectProperties)
{
if (ShouldSkipProperty(property))
continue;

// check if we have a special convert attached via attribute if so generate the required target
// properties with the correct converter
var virtualTypeAttribute = property.GetCustomAttributes().Where(a => a is IVirtualTypeAttribute).Select(a => a as IVirtualTypeAttribute).FirstOrDefault<IVirtualTypeAttribute>();
Expand All @@ -80,8 +82,12 @@ internal static class TableEntityDynamic
if (!entity.TryGetValue(property.Name, out objectValue))
continue;

if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?) || property.PropertyType == typeof(DateTimeOffset) || property.PropertyType == typeof(DateTimeOffset?) )
if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?) || property.PropertyType == typeof(DateTimeOffset) || property.PropertyType == typeof(DateTimeOffset?))
property.SetDateTimeOffsetValue(model, objectValue);
else if (property.PropertyType.IsEnum && int.TryParse(objectValue.ToString(), out var intEnum) && property.PropertyType.IsEnumDefined(intEnum))
property.SetValue(model, Enum.ToObject(property.PropertyType, intEnum));
else if (property.PropertyType.IsEnum && property.PropertyType.IsEnumDefined(objectValue.ToString()))
property.SetValue(model, Enum.Parse(property.PropertyType, objectValue.ToString()));
else
property.SetValue(model, objectValue);
}
Expand Down