Skip to content

Commit

Permalink
PR - EntityTableClient - Features/tableclient improve delete operatio…
Browse files Browse the repository at this point in the history
…ns (#62)

* chore

* update deleteoperations

* update unit tests

---------

Co-authored-by: medevod <[email protected]>
  • Loading branch information
medevod and medevod authored Jul 28, 2023
1 parent bcfc38d commit 0a01244
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 111 deletions.
36 changes: 21 additions & 15 deletions src/Azure.EntityServices.Tables/EntityTableClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected async Task NotifyCompleteAsync()
private IEntityAdapter<T, TableEntity> CreatePrimaryEntityBinderFromEntity(T entity)
=> new TableEntityAdapter<T>(entity, ResolvePartitionKey(entity), ResolvePrimaryKey(entity), _config.IgnoredProps, _entityTagBuilder, _options.SerializerOptions);

private IEntityAdapter<T, TableEntity> CreateEntityBinderFromTableEntity(TableEntity tableEntity)
private IEntityAdapter<T, TableEntity> CreateSecondaryEntityBinderFromTableEntity(TableEntity tableEntity)
=> new TableEntityAdapter<T>(tableEntity, _config.IgnoredProps, _entityTagBuilder, _options.SerializerOptions);

private TableBatchClient CreateTableBatchClient()
Expand Down Expand Up @@ -239,7 +239,7 @@ public EntityTableClient<T> Configure(EntityTableClientOptions options, EntityTa
_config = config;

_pipelineObserver = transactions => NotifyChangeAsync(transactions.Select(
transaction => new EntityContext<T>(CreateEntityBinderFromTableEntity(transaction.Entity as TableEntity),
transaction => new EntityContext<T>(CreateSecondaryEntityBinderFromTableEntity(transaction.Entity as TableEntity),
transaction.ActionType.MapToEntityOperation())));

_indextedTags =
Expand Down Expand Up @@ -307,7 +307,7 @@ public async Task<T> GetByIdAsync(string partition, object id, CancellationToken
{
return null;
}
return CreateEntityBinderFromTableEntity(response.Value).ReadFromEntityModel();
return CreateSecondaryEntityBinderFromTableEntity(response.Value).ReadFromEntityModel();
}
catch (RequestFailedException ex)
{
Expand All @@ -328,7 +328,7 @@ public async IAsyncEnumerable<IEnumerable<T>> GetAsync(Action<IQuery<T>> filter
{
await foreach (var page in QueryEntities(filter, null, null, cancellationToken))
{
yield return page.Values.Select(tableEntity => CreateEntityBinderFromTableEntity(tableEntity).ReadFromEntityModel());
yield return page.Values.Select(tableEntity => CreateSecondaryEntityBinderFromTableEntity(tableEntity).ReadFromEntityModel());
}
}

Expand All @@ -353,7 +353,7 @@ public async Task<EntityPage<T>> GetPagedAsync(
var currentCount = (iteratedCount ?? 0) + pageEnumerator.Current.Values.Count;

return new EntityPage<T>(pageEnumerator.Current.Values.Select(
tableEntity => CreateEntityBinderFromTableEntity(tableEntity).ReadFromEntityModel()),
tableEntity => CreateSecondaryEntityBinderFromTableEntity(tableEntity).ReadFromEntityModel()),
currentCount,
string.IsNullOrEmpty(pageEnumerator.Current.ContinuationToken),
pageEnumerator.Current.ContinuationToken);
Expand Down Expand Up @@ -418,7 +418,7 @@ public async Task<long> UpdateManyAsync(Action<T> updateAction, Action<IQuery<T>
{
if (cancellationToken.IsCancellationRequested) break;

var adapter = CreateEntityBinderFromTableEntity(tableEntity);
var adapter = CreateSecondaryEntityBinderFromTableEntity(tableEntity);
var entity = adapter.ReadFromEntityModel();

updateAction.Invoke(entity);
Expand All @@ -441,19 +441,14 @@ public async Task<long> UpdateManyAsync(Action<T> updateAction, Action<IQuery<T>
return count;
}

public Task DeleteAsync(T entity, CancellationToken cancellationToken = default)
{
return UpdateEntity(entity, EntityOperation.Delete, cancellationToken);
}

public async Task<IDictionary<string, object>> GetEntityMetadatasAsync(string partitionKey, string rowKey, CancellationToken cancellationToken = default)
{
var metadataKeys = _config.Tags.Keys.Union(_config.ComputedTags).Select(k => _entityTagBuilder.CreateTagName(k));

try
{
var response = await _asyncRetryPolicy.ExecuteAsync(async () => await _configuredClient.GetEntityAsync<TableEntity>(partitionKey, rowKey, metadataKeys, cancellationToken));
var entityBinder = CreateEntityBinderFromTableEntity(response.Value);
var entityBinder = CreateSecondaryEntityBinderFromTableEntity(response.Value);
entityBinder.ReadFromEntityModel();
return entityBinder?.Metadata ?? new Dictionary<string, object>();
}
Expand Down Expand Up @@ -509,13 +504,24 @@ public Task DeleteManyAsync(IEnumerable<T> entities, CancellationToken cancellat
return ApplyBatchOperations(EntityOperation.Delete, entities, cancellationToken);
}

public async Task DeleteByIdAsync(string partition, object id, CancellationToken cancellationToken = default)
public Task<bool> DeleteAsync(T entity, CancellationToken cancellationToken = default)
{
var partitionKey = ResolvePartitionKey(entity);
var rowKey = ResolvePrimaryKey(entity);

return DeleteByIdAsync(partitionKey, rowKey, cancellationToken);
}

public async Task<bool> DeleteByIdAsync(string partition, object id, CancellationToken cancellationToken = default)
{
var entity = await GetByIdAsync(partition, id, cancellationToken);
if (entity != null)
if (entity == null)
{
await DeleteAsync(entity, cancellationToken);
return false;
}

await UpdateEntity(entity, EntityOperation.Delete, cancellationToken);
return true;
}

protected async Task ApplyBatchOperations(EntityOperation operation, IEnumerable<T> entities, CancellationToken cancellationToken)
Expand Down
4 changes: 2 additions & 2 deletions src/Azure.EntityServices.Tables/IEntityTableClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ public interface IEntityTableClient<T>

Task<EntityPage<T>> GetPagedAsync(Action<IQuery<T>> filter = default, int? iteratorCount = null, int? maxPerPage = null, string nextPageToken = null, CancellationToken cancellationToken = default);

Task DeleteByIdAsync(string partition, object id, CancellationToken cancellationToken = default);
Task<bool> DeleteByIdAsync(string partition, object id, CancellationToken cancellationToken = default);

Task DeleteAsync(T entity, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(T entity, CancellationToken cancellationToken = default);

Task DeleteManyAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ namespace Azure.EntityServices.Tables
/// </summary>
public static class TableTagQueryExtensions
{
/// <summary>
/// Only retrieve non tagged entities, tagged entities partitionKey and rowKey does not start with reserved '~' character
/// Replicated rows are isolated by this keyword
/// By default, tagged entities was already ignored
/// </summary>
public static IFilterOperator<T> IgnoreTags<T>(this IQuery<T> query)

=> (query as IQueryCompose<T>)
Expand All @@ -19,7 +24,8 @@ public static IFilterOperator<T> IgnoreTags<T>(this IQuery<T> query)
.LessThan("~");

/// <summary>
/// Use this extension to include tagged entities (replicated partitions and rows)
/// Include tagged entities (replicated partitions and rows)
/// By default, tagged entities was ignored
/// </summary>
public static IQuery<T> IncludeTags<T>(this IQuery<T> query)
{
Expand All @@ -29,7 +35,7 @@ public static IQuery<T> IncludeTags<T>(this IQuery<T> query)
}

/// <summary>
/// Filter only tagged partitions and rows
/// Get only tagged partitions and rows that start with "~" character
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
Expand All @@ -46,7 +52,7 @@ public static IFilterOperator<T> WithOnlyTags<T>(this IQuery<T> query)
}

/// <summary>
/// Allow to retrieve all entities for a given tag
/// Allow to retrieve all entities for a specific tag (tagged entities)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
Expand Down
Loading

0 comments on commit 0a01244

Please sign in to comment.