Skip to content

Commit a71f713

Browse files
authored
(#38) PullAsync complete (#73)
1 parent 08482b3 commit a71f713

File tree

5 files changed

+334
-15
lines changed

5 files changed

+334
-15
lines changed

src/CommunityToolkit.Datasync.Client/Offline/Extensions.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,67 @@ namespace CommunityToolkit.Datasync.Client.Offline;
1313
/// </summary>
1414
public static class Extensions
1515
{
16+
/// <summary>
17+
/// Pulls the changes from the remote service for the specified dataset
18+
/// </summary>
19+
/// <param name="dataset">The dataset to pull from the remote service.</param>
20+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
21+
/// <returns>The results of the pull operation.</returns>
22+
public static Task<PullResult> PullAsync<TEntity>(this DbSet<TEntity> dataset, CancellationToken cancellationToken = default) where TEntity : class
23+
=> dataset.PullAsync(new PullOptions(), cancellationToken);
24+
25+
/// <summary>
26+
/// Pulls the changes from the remote service for the specified dataset
27+
/// </summary>
28+
/// <param name="dataset">The dataset to pull from the remote service.</param>
29+
/// <param name="options">The options to use on this pull request.</param>
30+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
31+
/// <returns>The results of the pull operation.</returns>
32+
public static Task<PullResult> PullAsync<TEntity>(this DbSet<TEntity> dataset, PullOptions options, CancellationToken cancellationToken = default) where TEntity : class
33+
{
34+
DbContext context = dataset.GetService<ICurrentDbContext>().Context;
35+
if (context is OfflineDbContext offlineContext)
36+
{
37+
return offlineContext.PullAsync([typeof(TEntity)], options, cancellationToken);
38+
}
39+
else
40+
{
41+
throw new DatasyncException($"Provided dataset is not a part of an {nameof(OfflineDbContext)}");
42+
}
43+
}
44+
45+
/// <summary>
46+
/// Pulls the changes from the remote service for all synchronizable entities.
47+
/// </summary>
48+
/// <param name="context">The offline database context to use.</param>
49+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
50+
/// <returns>The results of the pull operation.</returns>
51+
[ExcludeFromCodeCoverage]
52+
public static Task<PullResult> PullAsync(this OfflineDbContext context, CancellationToken cancellationToken = default)
53+
=> context.PullAsync(context.QueueManager.GetSynchronizableEntityTypes(), new PullOptions(), cancellationToken);
54+
55+
/// <summary>
56+
/// Pulls the changes from the remote service for all synchronizable entities.
57+
/// </summary>
58+
/// <param name="context">The offline database context to use.</param>
59+
/// <param name="options">The options to use on this pull request.</param>
60+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
61+
/// <returns>The results of the pull operation.</returns>
62+
[ExcludeFromCodeCoverage]
63+
public static Task<PullResult> PullAsync(this OfflineDbContext context, PullOptions options, CancellationToken cancellationToken = default)
64+
=> context.PullAsync(context.QueueManager.GetSynchronizableEntityTypes(), options, cancellationToken);
65+
66+
/// <summary>
67+
/// Pulls the changes from the remote service for the specified synchronizable entities.
68+
/// </summary>
69+
/// <param name="context">The offline database context to use.</param>
70+
/// <param name="entityTypes">The list of entity types to pull.</param>
71+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
72+
/// <returns>The results of the pull operation.</returns>
73+
[ExcludeFromCodeCoverage]
74+
public static Task<PullResult> PullAsync(this OfflineDbContext context, IEnumerable<Type> entityTypes, CancellationToken cancellationToken = default)
75+
=> context.PullAsync(entityTypes, new PullOptions(), cancellationToken);
76+
1677
/// <summary>
1778
/// Pushes the pending operations against the remote service for the provided dataset
1879
/// </summary>

src/CommunityToolkit.Datasync.Client/Offline/OfflineDbContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ public Task<PullResult> PullAsync(IEnumerable<Type> entityTypes, PullOptions pul
250250
return new PullRequest()
251251
{
252252
EntityType = type,
253-
QueryId = PullRequestBuilder.GetQueryIdFromQuery(type, entityOptions.QueryDescription),
253+
QueryId = PullRequestBuilder.GetQueryIdFromQuery(string.Empty, type, entityOptions.QueryDescription),
254254
HttpClient = entityOptions.HttpClient,
255255
Endpoint = entityOptions.Endpoint,
256256
QueryDescription = entityOptions.QueryDescription

src/CommunityToolkit.Datasync.Client/Offline/Operations/PullOperationManager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ public async Task<PullResult> ExecuteAsync(IEnumerable<PullRequest> requests, Pu
116116

117117
foreach (PullRequest request in requests)
118118
{
119-
request.QueryId = !string.IsNullOrEmpty(request.QueryId) ? request.QueryId : PullRequestBuilder.GetQueryIdFromQuery(request.EntityType, request.QueryDescription);
120119
DateTimeOffset lastSynchronization = await context.DeltaTokenStore.GetDeltaTokenAsync(request.QueryId, cancellationToken).ConfigureAwait(false);
121120
PrepareQueryDescription(request.QueryDescription, lastSynchronization);
122121
serviceRequestQueue.Enqueue(request);

src/CommunityToolkit.Datasync.Client/Offline/PullRequestBuilder.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ public PullRequestBuilder SetParallelOperations(int parallelOperations)
4040
return this;
4141
}
4242

43+
/// <summary>
44+
/// Determines whether to save the delta-token after every service request, or just after all the requests
45+
/// are completed.
46+
/// </summary>
47+
/// <param name="enabled">If true, save after every request.</param>
48+
/// <returns>The builder for chaining</returns>
49+
public PullRequestBuilder SaveAfterEveryServiceRequest(bool enabled)
50+
{
51+
this.pullOptions.SaveAfterEveryServiceRequest = enabled;
52+
return this;
53+
}
54+
4355
/// <summary>
4456
/// Adds a pull request for the default query as setup in the <see cref="OfflineDbContext.OnDatasyncInitialization(DatasyncOfflineOptionsBuilder)"/>
4557
/// method of your database context.
@@ -60,7 +72,7 @@ public PullRequestBuilder AddPullRequest<TEntity>() where TEntity : class
6072
EntityType = typeof(TEntity),
6173
HttpClient = options.HttpClient,
6274
QueryDescription = options.QueryDescription,
63-
QueryId = GetQueryIdFromQuery(typeof(TEntity), options.QueryDescription)
75+
QueryId = GetQueryIdFromQuery(string.Empty, typeof(TEntity), options.QueryDescription)
6476
};
6577
this.requests[request.QueryId] = request;
6678
return this;
@@ -96,7 +108,7 @@ public PullRequestBuilder AddPullRequest<TEntity>(Action<PullRequest<TEntity>> c
96108
EntityType = request.EntityType,
97109
HttpClient = request.HttpClient,
98110
QueryDescription = queryDescription,
99-
QueryId = string.IsNullOrEmpty(request.QueryId) ? GetQueryIdFromQuery(request.EntityType, queryDescription) : request.QueryId
111+
QueryId = GetQueryIdFromQuery(request.QueryId, request.EntityType, queryDescription)
100112
};
101113
this.requests[storedRequest.QueryId] = storedRequest;
102114
return this;
@@ -106,20 +118,25 @@ public PullRequestBuilder AddPullRequest<TEntity>(Action<PullRequest<TEntity>> c
106118
/// Obtain a query ID from the query and entity type. This is used when the developer does
107119
/// not specify a query ID.
108120
/// </summary>
121+
/// <param name="queryId">The specified query ID</param>
109122
/// <param name="entityType">The entity type.</param>
110123
/// <param name="query">The query,</param>
111124
/// <returns></returns>
112-
internal static string GetQueryIdFromQuery(Type entityType, QueryDescription query)
125+
internal static string GetQueryIdFromQuery(string queryId, Type entityType, QueryDescription query)
113126
{
114127
string odataQuery = query.ToODataQueryString();
115128
if (string.IsNullOrEmpty(odataQuery))
116129
{
117130
return entityType.FullName!;
118131
}
119132

120-
byte[] bytes = Encoding.UTF8.GetBytes(odataQuery);
121-
byte[] hashBytes = MD5.HashData(bytes);
122-
string queryId = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower();
133+
if (string.IsNullOrEmpty(queryId))
134+
{
135+
byte[] bytes = Encoding.UTF8.GetBytes(odataQuery);
136+
byte[] hashBytes = MD5.HashData(bytes);
137+
queryId = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower();
138+
}
139+
123140
return $"q-{entityType.FullName!}-{queryId}";
124141
}
125142

0 commit comments

Comments
 (0)