Skip to content

Commit

Permalink
Move code to use Azure.Data.Tables
Browse files Browse the repository at this point in the history
* Update to 12.4.0 of Azure Data Tables
* Update appveyor for VS2022
* Add notes about Azure.Data.Table changes to the readme
  • Loading branch information
Tazmainiandevil authored Jan 15, 2022
1 parent 2786b19 commit d37545d
Show file tree
Hide file tree
Showing 33 changed files with 1,729 additions and 2,035 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
**/obj
**/bin
/.vs
/.idea
*.user
*.nupkg
*.DotSettings

__azurite_db_table__.json
6 changes: 6 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
13 changes: 10 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TableStorage.Abstractions

Repository wrapper for Azure Table Storage in C# using the Microsoft.Azure.Cosmos.Table libraries and supporting .NET Standard 2.0.
Repository wrapper for Azure Table Storage in C# using the Azure.Data.Tables libraries and supporting .NET Standard 2.0 and tested in .NET Framework 4.8 and .NET 6.0

<image src="https://ci.appveyor.com/api/projects/status/github/Tazmainiandevil/TableStorage.Abstractions?branch=master&svg=true">
<a href="https://badge.fury.io/nu/TableStorage.Abstractions"><img src="https://badge.fury.io/nu/TableStorage.Abstractions.svg" alt="NuGet version" height="18"></a>
Expand Down Expand Up @@ -45,9 +45,16 @@ public class TableStorageOptions

Example entity:

__NOTE__: Azure.Data.Tables requires inheritance from the interface as the base class TableEntity is a sealed class.

```C#
public class TestTableEntity : TableEntity
public class TestTableEntity : ITableEntity
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }

public int Age { get; set; }
public string Email { get; set; }

Expand Down Expand Up @@ -281,4 +288,4 @@ __NOTE__: Currently only the basic methods are supported for this type of table,

Most methods have a synchronous and asynchronous version.

The unit tests rely on using Azure Storage Emulator (which can be found here <https://azure.microsoft.com/en-gb/downloads/>).
The unit tests rely on using Azurite Emulator which is now bundled with Visual Studio 2022 details can be found on [Microsoft Docs](https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio) for other installations including Visual Studio Code and Docker.
8 changes: 5 additions & 3 deletions TableStorage.Abstractions.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
<releaseNotes>$releaseNotes$</releaseNotes>
<dependencies>
<group targetFramework="netstandard2.0">
<dependency id="Microsoft.Azure.Cosmos.Table" version="1.0.8" />
<dependency id="Azure.Data.Tables" version="12.4.0" />
<dependency id="Azure.Storage.Common" version="12.9.0" />
<dependency id="FluentValidation" version="10.3.6" />
<dependency id="System.Linq.Async" version="5.1.0" />
<dependency id="System.Reactive" version="5.0.0" />
<dependency id="Useful.Extensions" version="3.0.1" />
<dependency id="System.Reactive" version="4.3.2" />
<dependency id="FluentValidation" version="8.6.1" />
</group>
</dependencies>
</metadata>
Expand Down
18 changes: 3 additions & 15 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version: 2.0.{build}
os: Visual Studio 2019
image: Visual Studio 2022
configuration: Release

# enable version patching with build version number
Expand All @@ -11,26 +11,14 @@ dotnet_csproj:
assembly_version: '{version}'
file_version: '{version}'

# temporary workaround for getting Azure Storage Emulator 5.2 installed
install:
- ps: |
$msiPath = "$env:TEMP\MicrosoftAzureStorageEmulator.msi"
(New-Object Net.WebClient).DownloadFile('https://go.microsoft.com/fwlink/?linkid=717179&clcid=0x409', $msiPath)
cmd /c start /wait msiexec /i $msiPath /quiet
del $msiPath
# restore NuGet packages before running
before_build:
# Display .NET Core version
- cmd: dotnet --version
# Display minimal restore text
- cmd: dotnet restore --verbosity m
# Prepare localdb
- cmd: SqlLocalDB.exe create MSSQLLocalDB
- cmd: SqlLocalDB.exe start MSSQLLocalDB
- cmd: SqlLocalDB.exe info MSSQLLocalDB
# Start the azure storage emulator
- '"%ProgramFiles(x86)%\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe" start'
# Start the azure storage emulator
- ps: start "${Env:ProgramFiles}\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator\azurite.exe"

build:
verbosity: minimal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Azure.Cosmos.Table;
using Azure.Data.Tables;
using TableStorage.Abstractions.Store;

namespace TableStorage.Abstractions.Factory
Expand Down
2 changes: 1 addition & 1 deletion src/TableStorage.Abstractions/Factory/TableStoreFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Azure.Cosmos.Table;
using Azure.Data.Tables;
using TableStorage.Abstractions.Store;

namespace TableStorage.Abstractions.Factory
Expand Down
5 changes: 2 additions & 3 deletions src/TableStorage.Abstractions/Models/PagedResult.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace TableStorage.Abstractions.Models
{
Expand All @@ -9,10 +8,10 @@ public class PagedResult<T>
public IReadOnlyCollection<T> Items { get; }
public bool IsFinalPage { get; }

internal PagedResult(IList<T> results, string continuationToken, bool isFinalPage)
internal PagedResult(IReadOnlyCollection<T> results, string continuationToken, bool isFinalPage)
{
ContinuationToken = continuationToken;
Items = new ReadOnlyCollection<T>(results);
Items = results;
IsFinalPage = isFinalPage;
}
}
Expand Down
27 changes: 16 additions & 11 deletions src/TableStorage.Abstractions/Parsers/TimeStringParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,38 @@ namespace TableStorage.Abstractions.Parsers
{
internal static class TimeStringParser
{
private const string SecondsSuffix = "s";
private const string MinuteSuffix = "m";
private const string HourSuffix = "h";
private const string DaySuffix = "d";

public static DateTime GetTimeAgo(string ago)
{
DateTime result;
if (ago.SafeEndsWith(MinuteSuffix, StringComparison.OrdinalIgnoreCase))
return DateTime.SpecifyKind(SystemTime.UtcNow().Subtract(GetTimeAgoTimeSpan(ago)), DateTimeKind.Utc);
}

public static TimeSpan GetTimeAgoTimeSpan(string ago)
{
TimeSpan result;
if (ago.SafeEndsWith(SecondsSuffix, StringComparison.OrdinalIgnoreCase))
{
var timePart = ago.SubstringBeforeValue(SecondsSuffix);
result = TimeSpan.FromSeconds(int.Parse(timePart));
}
else if (ago.SafeEndsWith(MinuteSuffix, StringComparison.OrdinalIgnoreCase))
{
var timePart = ago.SubstringBeforeValue(MinuteSuffix);
var fromMinutes = TimeSpan.FromMinutes(int.Parse(timePart));

result = SystemTime.UtcNow().Subtract(fromMinutes);
result = TimeSpan.FromMinutes(int.Parse(timePart));
}
else if (ago.SafeEndsWith(HourSuffix, StringComparison.OrdinalIgnoreCase))
{
var timePart = ago.SubstringBeforeValue(HourSuffix);
var fromHours = TimeSpan.FromHours(int.Parse(timePart));

result = SystemTime.UtcNow().Subtract(fromHours);
result = TimeSpan.FromHours(int.Parse(timePart));
}
else if (ago.SafeEndsWith(DaySuffix, StringComparison.OrdinalIgnoreCase))
{
var timePart = ago.SubstringBeforeValue(DaySuffix);
var fromDays = TimeSpan.FromDays(int.Parse(timePart));

result = SystemTime.UtcNow().Subtract(fromDays);
result = TimeSpan.FromDays(int.Parse(timePart));
}
else
{
Expand Down
30 changes: 16 additions & 14 deletions src/TableStorage.Abstractions/Store/ITableStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ public interface ITableStore<T> : ITableStoreCommon
/// <returns></returns>
Task DeleteByPartitionAsync(string partitionKey);

/// <summary>
/// Delete all records in the table
/// </summary>
/// <returns></returns>
void DeleteAll();

/// <summary>
/// Delete all records in the table
/// </summary>
Expand Down Expand Up @@ -161,8 +167,7 @@ public interface ITableStore<T> : ITableStoreCommon
/// <param name="pageSize">Size of the page.</param>
/// <param name="continuationTokenJson">The next page token.</param>
/// <returns>The Paged Result</returns>
PagedResult<T> GetByPartitionKeyPaged(string partitionKey, int pageSize = 100,
string continuationTokenJson = null);
PagedResult<T> GetByPartitionKeyPaged(string partitionKey, int pageSize = 100, string continuationTokenJson = null);

/// <summary>
/// Get the records by partition key, paged
Expand All @@ -171,8 +176,7 @@ PagedResult<T> GetByPartitionKeyPaged(string partitionKey, int pageSize = 100,
/// <param name="pageSize">Size of the page.</param>
/// <param name="continuationTokenJson">The next page token.</param>
/// <returns>The Paged Result</returns>
Task<PagedResult<T>> GetByPartitionKeyPagedAsync(string partitionKey, int pageSize = 100,
string continuationTokenJson = null);
Task<PagedResult<T>> GetByPartitionKeyPagedAsync(string partitionKey, int pageSize = 100, string continuationTokenJson = null);

/// <summary>
/// Get the records by row key
Expand Down Expand Up @@ -209,18 +213,16 @@ Task<PagedResult<T>> GetByPartitionKeyPagedAsync(string partitionKey, int pageSi
/// </summary>
/// <param name="rowKey">The row key.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="continuationTokenJson">The next page token.</param>
PagedResult<T> GetByRowKeyPaged(string rowKey, int pageSize = 100,
string continuationTokenJson = null);
/// <param name="continuationToken">The next page token.</param>
PagedResult<T> GetByRowKeyPaged(string rowKey, int pageSize = 100, string continuationToken = null);

/// <summary>
/// Get the records by row key
/// </summary>
/// <param name="rowKey">The row key.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="continuationTokenJson">The next page token.</param>
Task<PagedResult<T>> GetByRowKeyPagedAsync(string rowKey, int pageSize = 100,
string continuationTokenJson = null);
/// <param name="continuationToken">The next page token.</param>
Task<PagedResult<T>> GetByRowKeyPagedAsync(string rowKey, int pageSize = 100, string continuationToken = null);

/// <summary>
/// Get all the records in the table
Expand All @@ -238,17 +240,17 @@ Task<PagedResult<T>> GetByRowKeyPagedAsync(string rowKey, int pageSize = 100,
/// Gets all records paged.
/// </summary>
/// <param name="pageSize">Size of the page.</param>
/// <param name="pageToken">The page token.</param>
/// <param name="continuationToken">The page token.</param>
/// <returns>The Paged Result</returns>
PagedResult<T> GetAllRecordsPaged(int pageSize = 100, string pageToken = null);
PagedResult<T> GetAllRecordsPaged(int pageSize = 100, string continuationToken = null);

/// <summary>
/// Gets all records in the table, paged
/// </summary>
/// <param name="pageSize">Size of the page.</param>
/// <param name="pageToken">The page token</param>
/// <param name="continuationToken">The page token</param>
/// <returns>The Paged Result</returns>
Task<PagedResult<T>> GetAllRecordsPagedAsync(int pageSize = 100, string pageToken = null);
Task<PagedResult<T>> GetAllRecordsPagedAsync(int pageSize = 100, string continuationToken = null);

/// <summary>
/// Get the records and filter by a given predicate
Expand Down
4 changes: 2 additions & 2 deletions src/TableStorage.Abstractions/Store/ITableStoreCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ public interface ITableStoreCommon
/// <summary>
/// Does the table exist
/// </summary>
/// <returns></returns>
/// <returns>A boolean denoting if the table exists</returns>
bool TableExists();

/// <summary>
/// Does the table exist
/// </summary>
/// <returns></returns>
/// <returns>A boolean denoting if the table exists</returns>
Task<bool> TableExistsAsync();

/// <summary>
Expand Down
27 changes: 14 additions & 13 deletions src/TableStorage.Abstractions/Store/ITableStoreDynamic.cs
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
using Microsoft.Azure.Cosmos.Table;
using Azure.Data.Tables;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace TableStorage.Abstractions.Store
{
public interface ITableStoreDynamic : ITableStoreCommon
{

/// <summary>
/// Insert an record
/// </summary>
/// <param name="record">The record to insert</param>
void Insert<T>(T record) where T : class, ITableEntity;
void Insert<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Insert an record
/// </summary>
/// <param name="record">The record to insert</param>
Task InsertAsync<T>(T record) where T : class, ITableEntity;
Task InsertAsync<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Insert multiple records
/// </summary>
/// <param name="records">The records to insert</param>
void Insert<T>(IEnumerable<T> records) where T : class, ITableEntity;
void Insert<T>(IEnumerable<T> records) where T : class, ITableEntity, new();

/// <summary>
/// Insert multiple records
/// </summary>
/// <param name="records">The records to insert</param>
Task InsertAsync<T>(IEnumerable<T> records) where T : class, ITableEntity;
Task InsertAsync<T>(IEnumerable<T> records) where T : class, ITableEntity, new();

/// <summary>
/// Inserts or replaces the record
/// </summary>
/// <param name="record"></param>
void InsertOrReplace<T>(T record) where T : class, ITableEntity;
void InsertOrReplace<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Inserts or replaces the record
/// </summary>
/// <param name="record"></param>
Task InsertOrReplaceAsync<T>(T record) where T : class, ITableEntity;
Task InsertOrReplaceAsync<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Update an record
/// </summary>
/// <param name="record">The record to update</param>
void Update<T>(T record) where T : class, ITableEntity;
void Update<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Update an record
/// </summary>
/// <param name="record">The record to update</param>
Task UpdateAsync<T>(T record) where T : class, ITableEntity;
Task UpdateAsync<T>(T record) where T : class, ITableEntity, new();

/// <summary>
/// Delete a record
Expand All @@ -72,27 +73,27 @@ public interface ITableStoreDynamic : ITableStoreCommon
/// <param name="partitionKey"></param>
/// <param name="rowKey"></param>
/// <returns>The record found or null if not found</returns>
T GetRecord<T>(string partitionKey, string rowKey) where T : class, ITableEntity;
T GetRecord<T>(string partitionKey, string rowKey) where T : class, ITableEntity, new();

/// <summary>
/// Get an record by partition and row key
/// </summary>
/// <param name="partitionKey"></param>
/// <param name="rowKey"></param>
/// <returns>The record found or null if not found</returns>
Task<T> GetRecordAsync<T>(string partitionKey, string rowKey) where T : class, ITableEntity;
Task<T> GetRecordAsync<T>(string partitionKey, string rowKey) where T : class, ITableEntity, new();

/// <summary>
/// Get all the records in the table
/// </summary>
/// <returns>All records</returns>
IEnumerable<DynamicTableEntity> GetAllRecords();
IEnumerable<TableEntity> GetAllRecords();

/// <summary>
/// Get all the records in the table
/// </summary>
/// <returns>All records</returns>
Task<IEnumerable<DynamicTableEntity>> GetAllRecordsAsync();
Task<IEnumerable<TableEntity>> GetAllRecordsAsync();

/// <summary>
/// Get the records by partition key
Expand Down
Loading

0 comments on commit d37545d

Please sign in to comment.