From a0b98d2848090d83730a84aa7539d9c235316139 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 <alberteinstein1980@gmx.de> Date: Thu, 19 Sep 2019 14:26:14 +0200 Subject: [PATCH] Add QueryAll functionality; --- .../ClientQueryAllEnumerator.cs | 97 +++++++++++++++++++ .../ClientQueryProvider.cs | 14 ++- .../ClientQueryableCollection.cs | 4 +- .../LinqExtensions.cs | 5 + 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 commercetools.Sdk/commercetools.Sdk.Client/ClientQueryAllEnumerator.cs diff --git a/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryAllEnumerator.cs b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryAllEnumerator.cs new file mode 100644 index 00000000..af1aa6ff --- /dev/null +++ b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryAllEnumerator.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using commercetools.Sdk.Domain; + +namespace commercetools.Sdk.Client +{ + public class ClientQueryAllEnumerator<TCommand> : IEnumerator<TCommand> + { + private const int DefaultOffset = 0; + private const int DefaultLimit = 20; + + private IClient client; + private QueryCommand<TCommand> command; + + private List<TCommand> resultSet; + private int position = -1; + + public ClientQueryAllEnumerator(IClient client, QueryCommand<TCommand> command) + { + if (client == null) + { + throw new FieldAccessException("Client cannot be null"); + } + + this.client = client; + this.command = command; + } + + public bool MoveNext() + { + this.position++; + if (this.command.QueryParameters is IPageable pageableParameters && pageableParameters.Limit == null) + { + var limit = DefaultLimit; + if (this.resultSet == null || this.position % limit == 0) + { + // Retrieve new set of results + var originalOffset = pageableParameters.Offset; + + // Reset offset to original value after retrieveing for an eventual reuse of the command somewhere else + pageableParameters.Offset = (originalOffset ?? DefaultOffset) + this.position; + RetrieveResults(command); + pageableParameters.Offset = originalOffset; + } + + return this.position % limit < this.resultSet.Count; + } + + // If command is not paged + if (this.resultSet == null) + { + RetrieveResults(this.command); + } + + return this.position < this.resultSet.Count; + } + + private void RetrieveResults(QueryCommand<TCommand> queryCommand) + { + var queryTask = this.client.ExecuteAsync(queryCommand); + this.resultSet = queryTask.Result.Results; + } + + public void Reset() + { + this.resultSet = null; + this.position = -1; + } + + public TCommand Current + { + get + { + if (this.command.QueryParameters is IPageable pageableParameters) + { + var limit = pageableParameters.Limit ?? DefaultLimit; + return this.resultSet[this.position % limit]; + } + + return this.resultSet[this.position]; + } + } + + object IEnumerator.Current => Current; + + public void Dispose() + { + this.resultSet?.Clear(); + + this.client = null; + this.command = null; + this.resultSet = null; + } + } +} diff --git a/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryProvider.cs b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryProvider.cs index 9d3785e3..a935d683 100644 --- a/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryProvider.cs +++ b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryProvider.cs @@ -15,11 +15,17 @@ public class ClientQueryProvider<T> : IQueryProvider private readonly IClient client; private IList<T> result = new List<T>(); + private IEnumerator<T> enumerator; - public ClientQueryProvider(IClient client, QueryCommand<T> command) + public ClientQueryProvider(IClient client, QueryCommand<T> command, bool queryAll) { this.client = client; this.Command = command; + + if (queryAll) + { + enumerator = new ClientQueryAllEnumerator<T>(client, command); + } } public QueryCommand<T> Command { get; } @@ -128,6 +134,12 @@ public object Execute(Expression expression) public TResult Execute<TResult>(Expression expression) { + if (enumerator != null) + { + enumerator.Reset(); + return (TResult)enumerator; + } + if (this.client == null) { throw new FieldAccessException("Client cannot be null"); diff --git a/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryableCollection.cs b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryableCollection.cs index 5d48b72d..381e53aa 100644 --- a/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryableCollection.cs +++ b/commercetools.Sdk/commercetools.Sdk.Client/ClientQueryableCollection.cs @@ -11,9 +11,9 @@ namespace commercetools.Sdk.Client public class ClientQueryableCollection<T> : IOrderedQueryable<T> { - public ClientQueryableCollection(IClient client, QueryCommand<T> command) + public ClientQueryableCollection(IClient client, QueryCommand<T> command, bool queryAll = false) { - this.Provider = new ClientQueryProvider<T>(client, command); + this.Provider = new ClientQueryProvider<T>(client, command, queryAll); this.Expression = Expression.Constant(this); } diff --git a/commercetools.Sdk/commercetools.Sdk.Client/LinqExtensions.cs b/commercetools.Sdk/commercetools.Sdk.Client/LinqExtensions.cs index f2de9e1b..20ca6bef 100644 --- a/commercetools.Sdk/commercetools.Sdk.Client/LinqExtensions.cs +++ b/commercetools.Sdk/commercetools.Sdk.Client/LinqExtensions.cs @@ -16,6 +16,11 @@ public static ClientQueryableCollection<T> Query<T>(this IClient client) return new ClientQueryableCollection<T>(client, new QueryCommand<T>()); } + public static ClientQueryableCollection<T> QueryAll<T>(this IClient client) + { + return new ClientQueryableCollection<T>(client, new QueryCommand<T>(), true); + } + public static ClientQueryableCollection<ProductProjection> SearchProducts(this IClient client) { return new ClientQueryableCollection<ProductProjection>(client, new SearchProductProjectionsCommand());