Skip to content

Update libs #5

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

Merged
merged 5 commits into from
Jan 23, 2022
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
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ This simple library seeks to take care of the mapping for us, so that you can co

The library will convert simple properties to fields in Azure Table Storage. Complex types will serialize as json.

## :bangbang: Important Note About Versioning
`TableStorage.Abstractions.TableEntityConverters` uses semantic versioning. Anything changes to a major release should not be breaking, e.g. upgrading to 1.5 from 1.4 should not require a code change.

The upgrade from 1.5 to 2.0 does not introduce changes needed in your use of `TableStorage.Abstractions.TableEntityConverters`, however the underlying table storage SDK is now using the newer [Azure.Data.Tables](https://www.nuget.org/packages/Azure.Data.Tables/) instead of the older [Microsoft.Azure.Cosmos.Table](https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Table/) SDK.

If you directly use Microsoft's Table Storage SDK, you will need to use `Azure.Data.Tables`. It should not require much change, but nevertheless it is a change. If you do not want to upgrade at this time, stick with `TableStorage.Abstractions.TableEntityConverters` 1.5.


Examples
========
We'll use the following two classes for our examples
Expand Down Expand Up @@ -144,8 +152,8 @@ property name and the value is a `PropertyConverter`, which specifies how to con
var propertyConverters = new PropertyConverters<Car> {
[nameof(Car.ReleaseDate)] =
new PropertyConverter<Car>(x =>
new EntityProperty(car.ReleaseDate.ToString("yyyy-M-d")),
(c,p) =>c.ReleaseDate = DateTime.Parse(p.StringValue)
car.ReleaseDate.ToString("yyyy-M-d"),
(c,p) => c.ReleaseDate = p.ToString())
)
};
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.Azure.Cosmos.Table;
using Azure.Data.Tables;

namespace TableStorage.Abstractions.TableEntityConverters
{
Expand All @@ -22,12 +22,12 @@ public static void SetDefaultJsonSerializerSettings (JsonSerializerSettings json
_defaultJsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
}

public static DynamicTableEntity ToTableEntity<T>(this T o, string partitionKey, string rowKey,
public static TableEntity ToTableEntity<T>(this T o, string partitionKey, string rowKey,
params Expression<Func<T, object>>[] ignoredProperties)
{
return ToTableEntity(o, partitionKey, rowKey, _defaultJsonSerializerSettings, default, ignoredProperties);
}
public static DynamicTableEntity ToTableEntity<T>(this T o, string partitionKey, string rowKey,
public static TableEntity ToTableEntity<T>(this T o, string partitionKey, string rowKey,
JsonSerializerSettings jsonSerializerSettings,
PropertyConverters<T> propertyConverters = default,
params Expression<Func<T, object>>[] ignoredProperties)
Expand All @@ -39,14 +39,14 @@ public static DynamicTableEntity ToTableEntity<T>(this T o, string partitionKey,
return CreateTableEntity(o, properties, partitionKey, rowKey, jsonSerializerSettings, propertyConverters);
}

public static DynamicTableEntity ToTableEntity<T>(this T o, Expression<Func<T, object>> partitionProperty,
public static TableEntity ToTableEntity<T>(this T o, Expression<Func<T, object>> partitionProperty,
Expression<Func<T, object>> rowProperty,
params Expression<Func<T, object>>[] ignoredProperties)
{
return ToTableEntity(o, partitionProperty, rowProperty, _defaultJsonSerializerSettings, null, ignoredProperties);
}

public static DynamicTableEntity ToTableEntity<T>(this T o, Expression<Func<T, object>> partitionProperty,
public static TableEntity ToTableEntity<T>(this T o, Expression<Func<T, object>> partitionProperty,
Expression<Func<T, object>> rowProperty, JsonSerializerSettings jsonSerializerSettings,
PropertyConverters<T> propertyConverters = default,
params Expression<Func<T, object>>[] ignoredProperties)
Expand Down Expand Up @@ -76,14 +76,14 @@ public static DynamicTableEntity ToTableEntity<T>(this T o, Expression<Func<T, o
return CreateTableEntity(o, properties, partitionKey, rowKey, jsonSerializerSettings, propertyConverters);
}

public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
public static T FromTableEntity<T, TP, TR>(this TableEntity entity,
Expression<Func<T, object>> partitionProperty,
Expression<Func<T, object>> rowProperty) where T : new()
{
return FromTableEntity<T, TP, TR>(entity, partitionProperty, rowProperty, _defaultJsonSerializerSettings);
}

public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
public static T FromTableEntity<T, TP, TR>(this TableEntity entity,
Expression<Func<T, object>> partitionProperty,
Expression<Func<T, object>> rowProperty,
JsonSerializerSettings jsonSerializerSettings,
Expand All @@ -106,7 +106,7 @@ public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
rowProperty, convertRow, jsonSerializerSettings, propertyConverters);
}

public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
public static T FromTableEntity<T, TP, TR>(this TableEntity entity,
Expression<Func<T, object>> partitionProperty,
Func<string, TP> convertPartitionKey, Expression<Func<T, object>> rowProperty,
Func<string, TR> convertRowKey) where T : new()
Expand All @@ -115,7 +115,7 @@ public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
convertRowKey, _defaultJsonSerializerSettings);
}

public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
public static T FromTableEntity<T, TP, TR>(this TableEntity entity,
Expression<Func<T, object>> partitionProperty,
Func<string, TP> convertPartitionKey, Expression<Func<T, object>> rowProperty,
Func<string, TR> convertRowKey, JsonSerializerSettings jsonSerializerSettings,
Expand Down Expand Up @@ -156,12 +156,12 @@ public static T FromTableEntity<T, TP, TR>(this DynamicTableEntity entity,
return o;
}

public static T FromTableEntity<T>(this DynamicTableEntity entity) where T : new()
public static T FromTableEntity<T>(this TableEntity entity) where T : new()
{
return FromTableEntity<T>(entity, _defaultJsonSerializerSettings);
}

public static T FromTableEntity<T>(this DynamicTableEntity entity,
public static T FromTableEntity<T>(this TableEntity entity,
JsonSerializerSettings jsonSerializerSettings, PropertyConverters<T> propertyConverters = default) where T : new()
{
_ = jsonSerializerSettings ?? throw new ArgumentNullException(nameof(jsonSerializerSettings));
Expand All @@ -188,10 +188,10 @@ internal static string GetPropertyNameFromExpression<T>(Expression<Func<T, objec
return name;
}

private static void SetTimestamp<T>(DynamicTableEntity entity, T o, List<PropertyInfo> properties) where T : new()
private static void SetTimestamp<T>(TableEntity entity, T o, List<PropertyInfo> properties) where T : new()
{
var timestampProperty = properties
.FirstOrDefault(p => p.Name == nameof(DynamicTableEntity.Timestamp));
.FirstOrDefault(p => p.Name == nameof(TableEntity.Timestamp));

if (timestampProperty != null)
{
Expand All @@ -202,7 +202,7 @@ internal static string GetPropertyNameFromExpression<T>(Expression<Func<T, objec

if (timestampProperty.PropertyType == typeof(DateTime))
{
timestampProperty.SetValue(o, entity.Timestamp.UtcDateTime);
timestampProperty.SetValue(o, entity.Timestamp?.UtcDateTime);
}

if (timestampProperty.PropertyType == typeof(string))
Expand All @@ -212,48 +212,48 @@ internal static string GetPropertyNameFromExpression<T>(Expression<Func<T, objec
}
}

private static void FillProperties<T>(DynamicTableEntity entity, T o, List<PropertyInfo> properties, JsonSerializerSettings jsonSerializerSettings, PropertyConverters<T> propertyConverters) where T : new()
private static void FillProperties<T>(TableEntity entity, T o, List<PropertyInfo> properties, JsonSerializerSettings jsonSerializerSettings, PropertyConverters<T> propertyConverters) where T : new()
{
foreach (var propertyInfo in properties)
{
if (propertyConverters != null && entity.Properties.ContainsKey(propertyInfo.Name) && propertyConverters.ContainsKey(propertyInfo.Name))
if (propertyConverters != null && entity.Keys.Contains(propertyInfo.Name) && propertyConverters.ContainsKey(propertyInfo.Name))
{
propertyConverters[propertyInfo.Name].SetObjectProperty(o, entity.Properties[propertyInfo.Name]);
propertyConverters[propertyInfo.Name].SetObjectProperty(o, entity[propertyInfo.Name]);
}
else if (entity.Properties.ContainsKey(propertyInfo.Name) && propertyInfo.Name != nameof(DynamicTableEntity.Timestamp))
else if (entity.Keys.Contains(propertyInfo.Name) && propertyInfo.Name != nameof(TableEntity.Timestamp))
{
var val = entity.Properties[propertyInfo.Name].PropertyAsObject;
var val = entity[propertyInfo.Name];

if (val != null && (propertyInfo.PropertyType == typeof(DateTimeOffset) || propertyInfo.PropertyType == typeof(DateTimeOffset?)))
{
val = entity.Properties[propertyInfo.Name].DateTimeOffsetValue;
val = entity.GetDateTimeOffset(propertyInfo.Name);
}

if (val != null && propertyInfo.PropertyType == typeof(double))
{
val = entity.Properties[propertyInfo.Name].DoubleValue;
val = entity.GetDouble(propertyInfo.Name);
}

if (val != null && propertyInfo.PropertyType == typeof(int))
{
val = entity.Properties[propertyInfo.Name].Int32Value;
val = entity.GetInt32(propertyInfo.Name);
}

if (val != null && propertyInfo.PropertyType == typeof(long))
{
val = entity.Properties[propertyInfo.Name].Int64Value;
val = entity.GetInt64(propertyInfo.Name);
}

if (val != null && propertyInfo.PropertyType == typeof(Guid))
{
val = entity.Properties[propertyInfo.Name].GuidValue;
val = entity.GetGuid(propertyInfo.Name);
}

propertyInfo.SetValue(o, val);
}
else if (entity.Properties.ContainsKey($"{propertyInfo.Name}Json"))
else if (entity.Keys.Contains($"{propertyInfo.Name}Json"))
{
var val = entity.Properties[$"{propertyInfo.Name}Json"].StringValue;
var val = entity.GetString($"{propertyInfo.Name}Json");
if (val != null)
{
var propVal = JsonConvert.DeserializeObject(val, propertyInfo.PropertyType, jsonSerializerSettings ?? _defaultJsonSerializerSettings);
Expand All @@ -263,15 +263,15 @@ internal static string GetPropertyNameFromExpression<T>(Expression<Func<T, objec
}
}

private static DynamicTableEntity CreateTableEntity<T>(object o, List<PropertyInfo> properties,
private static TableEntity CreateTableEntity<T>(object o, List<PropertyInfo> properties,
string partitionKey, string rowKey, JsonSerializerSettings jsonSerializerSettings, PropertyConverters<T> propertyConverters)
{
var entity = new DynamicTableEntity(partitionKey, rowKey);
var entity = new TableEntity(partitionKey, rowKey);
foreach (var propertyInfo in properties)
{
var name = propertyInfo.Name;
var val = propertyInfo.GetValue(o);
EntityProperty entityProperty;
object entityProperty;
if (propertyConverters != null && propertyConverters.ContainsKey(name))
{
entityProperty = propertyConverters[name].ToTableEntityProperty((T)o);
Expand All @@ -281,50 +281,50 @@ private static DynamicTableEntity CreateTableEntity<T>(object o, List<PropertyIn
switch (val)
{
case int x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case short x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case byte x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case string x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case double x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case DateTime x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case DateTimeOffset x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case bool x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case byte[] x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case long x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case Guid x:
entityProperty = new EntityProperty(x);
entityProperty = x;
break;
case null:
entityProperty = new EntityProperty((int?)null);
entityProperty = null;
break;
default:
name += "Json";
entityProperty = new EntityProperty(JsonConvert.SerializeObject(val,
jsonSerializerSettings ?? _defaultJsonSerializerSettings));
entityProperty = JsonConvert.SerializeObject(val,
jsonSerializerSettings ?? _defaultJsonSerializerSettings);
break;
}
}

entity.Properties[name] = entityProperty;
entity[name] = entityProperty;
}
return entity;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using System;
using System.Collections.Generic;
using Microsoft.Azure.Cosmos.Table;

namespace TableStorage.Abstractions.TableEntityConverters
{
public class PropertyConverter<T>
{
public Func<T, EntityProperty> ToTableEntityProperty { get; }
public Action<T,EntityProperty> SetObjectProperty { get; }
public Func<T, object> ToTableEntityProperty { get; }
public Action<T, object> SetObjectProperty { get; }

public PropertyConverter(Func<T, EntityProperty> toTableEntityProperty, Action<T, EntityProperty> setObjectProperty)
public PropertyConverter(Func<T, object> toTableEntityProperty, Action<T, object> setObjectProperty)
{
ToTableEntityProperty = toTableEntityProperty;
SetObjectProperty = setObjectProperty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<Version>1.3.2.0</Version>
<Version>2.0.0.0</Version>
<Authors>Giovanni Galbo</Authors>
<Company>Giovanni Galbo</Company>
<Description>Easily convert POCOs (Plain Old CLR Objects) to Azure Table Storage TableEntities and vice versa.</Description>
<Copyright>Giovanni Galbo © 2021</Copyright>
<Copyright>Giovanni Galbo © 2022</Copyright>
<PackageLicenseUrl></PackageLicenseUrl>
<PackageProjectUrl>https://github.com/giometrix/TableStorage.Abstractions.TableEntityConverters</PackageProjectUrl>
<RepositoryUrl>https://github.com/giometrix/TableStorage.Abstractions.TableEntityConverters</RepositoryUrl>
<PackageTags>table-storage azure-table-storage poco table-entities</PackageTags>
<PackageReleaseNotes>Allows for custom serialization of properties</PackageReleaseNotes>
<PackageReleaseNotes>Updated to use newer Azure.Data.Tables SDK</PackageReleaseNotes>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand All @@ -20,13 +20,17 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<AssemblyVersion>1.3.2.0</AssemblyVersion>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<Nullable>disable</Nullable>
<PackageVersion>1.5.0.0</PackageVersion>
<PackageVersion>2.0.0.0</PackageVersion>
<SignAssembly>False</SignAssembly>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Azure.Data.Tables" Version="12.4.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>


Expand All @@ -35,10 +39,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.8" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\..\xtensible-x.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
Expand Down
Loading