Skip to content
This repository has been archived by the owner on Feb 29, 2020. It is now read-only.

Commit

Permalink
[client][managed][offline] * remove redundant overloads in interface …
Browse files Browse the repository at this point in the history
…and move them to extensions

* abstract out system property reading into object reader
  • Loading branch information
hasankhan committed Oct 16, 2014
1 parent 62e33af commit d0a46b6
Show file tree
Hide file tree
Showing 15 changed files with 312 additions and 100 deletions.
2 changes: 1 addition & 1 deletion sdk/Javascript/src/External/queryjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// ----------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices.Sync;
Expand Down Expand Up @@ -36,6 +37,52 @@ public static Task PullAsync(this IMobileServiceSyncTable table, string query)
return table.PullAsync(null, query, null, cancellationToken: CancellationToken.None);
}

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
/// <param name="table">The instance of table to execute pull on.</param>
/// <param name="queryKey">
/// A string that uniquely identifies this query and is used to keep track of its sync state. Supplying this parameter enables incremental sync whenever the same key is used again.
/// </param>
/// <param name="query">
/// An OData query that determines which items to
/// pull from the remote table.
/// </param>
/// <param name="parameters">
/// A dictionary of user-defined parameters and values to include in
/// the request URI query string.
/// </param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe
/// </param>
/// <returns>
/// A task that completes when pull operation has finished.
/// </returns>
public static Task PullAsync(this IMobileServiceSyncTable table, string queryKey, string query, IDictionary<string, string> parameters, CancellationToken cancellationToken)
{
return table.PullAsync(queryKey, query, parameters, true, cancellationToken: cancellationToken);
}

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
/// <param name="table">The instance of table to execute pull on.</param>
/// <param name="queryKey">
/// A string that uniquely identifies this query and is used to keep track of its sync state. Supplying this parameter enables incremental sync whenever the same key is used again.
/// </param>
/// <param name="query">
/// An OData query that determines which items to
/// pull from the remote table.
/// </param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe
/// </param>
/// <returns>
/// A task that completes when pull operation has finished.
/// </returns>
public static Task PullAsync<T, U>(this IMobileServiceSyncTable<T> table, string queryKey, IMobileServiceTableQuery<U> query, CancellationToken cancellationToken)
{
return table.PullAsync(queryKey, query, pushOtherTables: true, cancellationToken: cancellationToken);
}

/// <summary>
/// Pulls all items that match the given query
/// from the associated remote table.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Table\MobileServiceObjectReader.cs" />
<Compile Include="Table\MobileServiceSystemColumns.cs" />
<Compile Include="Table\MobileServiceSystemProperties.cs" />
<Compile Include="Table\Query\IQueryResultEnumerable.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------

using System;
using Newtonsoft.Json.Linq;

namespace Microsoft.WindowsAzure.MobileServices
{
internal class MobileServiceObjectReader
{
public string VersionPropertyName { get; set; }
public string DeletedPropertyName { get; set; }
public string UpdatedAtPropertyName { get; set; }
public string IdPropertyName { get; set; }
public string CreatedAtPropertyName { get; set; }

public MobileServiceObjectReader()
{
this.VersionPropertyName = MobileServiceSystemColumns.Version;
this.DeletedPropertyName = MobileServiceSystemColumns.Deleted;
this.UpdatedAtPropertyName = MobileServiceSystemColumns.UpdatedAt;
this.IdPropertyName = MobileServiceSystemColumns.Id;
this.CreatedAtPropertyName = MobileServiceSystemColumns.CreatedAt;
}

public string GetVersion(JObject item)
{
return (string)item[this.VersionPropertyName];
}

public string GetId(JObject item)
{
return (string)item[IdPropertyName];
}

public bool IsDeleted(JObject item)
{
JToken deletedToken = item[DeletedPropertyName];
bool isDeleted = deletedToken != null && deletedToken.Value<bool>();
return isDeleted;
}

public DateTimeOffset? GetUpdatedAt(JObject item)
{
return GetDateTimeOffset(item, UpdatedAtPropertyName);
}

public DateTimeOffset? GetCreatedAt(JObject item)
{
return GetDateTimeOffset(item, CreatedAtPropertyName);
}

private static DateTimeOffset? GetDateTimeOffset(JObject item, string name)
{
JToken updatedAtToken = item[name];
if (updatedAtToken != null)
{
return updatedAtToken.ToObject<DateTimeOffset?>();
}
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,6 @@ public interface IMobileServiceSyncTable<T> : IMobileServiceSyncTable
/// </returns>
Task DeleteAsync(T instance);

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
/// <param name="queryKey">
/// A string that uniquely identifies this query and is used to keep track of its sync state. Supplying this parameter enables incremental sync whenever the same key is used again.
/// </param>
/// <param name="query">
/// An OData query that determines which items to
/// pull from the remote table.
/// </param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe
/// </param>
/// <returns>
/// A task that completes when pull operation has finished.
/// </returns>
Task PullAsync<U>(string queryKey, IMobileServiceTableQuery<U> query, CancellationToken cancellationToken);

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,6 @@ public interface IMobileServiceSyncTable
/// </returns>
Task<JObject> LookupAsync(string id);

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
/// <param name="queryKey">
/// A string that uniquely identifies this query and is used to keep track of its sync state. Supplying this parameter enables incremental sync whenever the same key is used again.
/// </param>
/// <param name="query">
/// An OData query that determines which items to
/// pull from the remote table.
/// </param>
/// <param name="parameters">
/// A dictionary of user-defined parameters and values to include in
/// the request URI query string.
/// </param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe
/// </param>
/// <returns>
/// A task that completes when pull operation has finished.
/// </returns>
Task PullAsync(string queryKey, string query, IDictionary<string, string> parameters, CancellationToken cancellationToken);

/// <summary>
/// Pulls all items that match the given query from the associated remote table. Supports incremental sync. For more information, see http://go.microsoft.com/fwlink/?LinkId=506788.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@ public async Task<JObject> LookupAsync(string tableName, string id)
/// List of tables that may have related records that need to be push before this table is pulled down.
/// When no table is specified, all tables are considered related.
/// </param>
/// <param name="reader">An instance of <see cref="MobileServiceObjectReader"/></param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe
/// </param>
/// <returns>
/// A task that completes when pull operation has finished.
/// </returns>
public async Task PullAsync(string tableName, string queryKey, string query, MobileServiceRemoteTableOptions options, IDictionary<string, string> parameters, IEnumerable<string> relatedTables, CancellationToken cancellationToken)
public async Task PullAsync(string tableName, string queryKey, string query, MobileServiceRemoteTableOptions options, IDictionary<string, string> parameters, IEnumerable<string> relatedTables, MobileServiceObjectReader reader, CancellationToken cancellationToken)
{
await this.EnsureInitializedAsync();

Expand Down Expand Up @@ -221,10 +222,8 @@ public async Task PullAsync(string tableName, string queryKey, string query, Mob
// let us not burden the server to calculate the count when we don't need it for pull
queryDescription.IncludeTotalCount = false;

var pull = new PullAction(table, this, queryKey, queryDescription, parameters, relatedTables, this.opQueue, this.settings, this.Store, options, cancellationToken);
Task discard = this.syncQueue.Post(pull.ExecuteAsync, cancellationToken);

await pull.CompletionTask;
var action = new PullAction(table, this, queryKey, queryDescription, parameters, relatedTables, this.opQueue, this.settings, this.Store, options, reader, cancellationToken);
await this.ExecuteSyncAction(action);
}

public async Task PurgeAsync(string tableName, string queryKey, string query, CancellationToken cancellationToken)
Expand All @@ -233,10 +232,8 @@ public async Task PurgeAsync(string tableName, string queryKey, string query, Ca

var table = await this.GetTable(tableName);
var queryDescription = MobileServiceTableQueryDescription.Parse(tableName, query);
var purge = new PurgeAction(table, queryKey, queryDescription, this, this.opQueue, this.settings, this.Store, cancellationToken);
Task discard = this.syncQueue.Post(purge.ExecuteAsync, cancellationToken);

await purge.CompletionTask;
var action = new PurgeAction(table, queryKey, queryDescription, this, this.opQueue, this.settings, this.Store, cancellationToken);
await this.ExecuteSyncAction(action);
}

public Task PushAsync(CancellationToken cancellationToken)
Expand All @@ -248,17 +245,22 @@ public async Task PushAsync(CancellationToken cancellationToken, params string[]
{
await this.EnsureInitializedAsync();

var push = new PushAction(this.opQueue,
var action = new PushAction(this.opQueue,
this.Store,
tableNames,
this.Handler,
this.client,
this,
cancellationToken);

Task discard = this.syncQueue.Post(push.ExecuteAsync, cancellationToken);
await this.ExecuteSyncAction(action);
}

public async Task ExecuteSyncAction(SyncAction action)
{
Task discard = this.syncQueue.Post(action.ExecuteAsync, action.CancellationToken);

await push.CompletionTask;
await action.CompletionTask;
}

public virtual async Task<MobileServiceTable> GetTable(string tableName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,6 @@ public Task<IEnumerable<U>> ReadAsync<U>(IMobileServiceTableQuery<U> query)
return this.queryProvider.Execute(query);
}

public Task PullAsync<U>(string queryKey, IMobileServiceTableQuery<U> query, CancellationToken cancellationToken)
{
return PullAsync(queryKey, query, cancellationToken, new string[0]);
}

public Task PullAsync<U>(string queryKey, IMobileServiceTableQuery<U> query, CancellationToken cancellationToken, params string[] tableNames)
{
if (query == null)
{
throw new ArgumentNullException("query");
}
string queryString = this.queryProvider.ToODataString(query);

return this.PullAsync(queryKey, queryString, query.Parameters, cancellationToken, tableNames);
}

public Task PullAsync<U>(string queryKey, IMobileServiceTableQuery<U> query, bool pushOtherTables, CancellationToken cancellationToken)
{
if (query == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,17 @@ public Task<JToken> ReadAsync(string query)
return this.syncContext.ReadAsync(this.TableName, query);
}

public Task PullAsync(string queryKey, string query, IDictionary<string, string> parameters, CancellationToken cancellationToken)
{
return PullAsync(queryKey, query, parameters, cancellationToken, new string[0]);
}

public Task PullAsync(string queryKey, string query, IDictionary<string, string> parameters, CancellationToken cancellationToken, params string[] tableNames)
public Task PullAsync(string queryKey, string query, IDictionary<string, string> parameters, MobileServiceObjectReader reader, CancellationToken cancellationToken, params string[] relatedTables)
{
ValidateQueryKey(queryKey);
return this.syncContext.PullAsync(this.TableName, queryKey, query, this.SupportedOptions, parameters, tableNames ?? new string[0], cancellationToken);

return this.syncContext.PullAsync(this.TableName, queryKey, query, this.SupportedOptions, parameters, relatedTables, reader, cancellationToken);
}

public Task PullAsync(string queryKey, string query, IDictionary<string, string> parameters, bool pushOtherTables, CancellationToken cancellationToken)
{
ValidateQueryKey(queryKey);
return this.syncContext.PullAsync(this.TableName, queryKey, query, this.SupportedOptions, parameters, pushOtherTables ? new string[0] : null, cancellationToken);
return this.syncContext.PullAsync(this.TableName, queryKey, query, this.SupportedOptions, parameters, pushOtherTables ? new string[0] : null, null, cancellationToken);
}

public Task PurgeAsync(string queryKey, string query, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@ public PullAction(MobileServiceTable table,
MobileServiceSyncSettingsManager settings,
IMobileServiceLocalStore store,
MobileServiceRemoteTableOptions options,
MobileServiceObjectReader reader,
CancellationToken cancellationToken)
: base(table, queryKey, query, relatedTables, context, operationQueue, settings, store, cancellationToken)
{
this.options = options;
this.parameters = parameters;
this.cursor = new PullCursor(query);
this.Reader = reader ?? new MobileServiceObjectReader();
}

public MobileServiceObjectReader Reader { get; private set; }

protected override bool CanDeferIfDirty
{
get { return true; }
Expand Down Expand Up @@ -85,16 +89,16 @@ private async Task ProcessAll(JArray items)
break;
}

string id = (string)item[MobileServiceSystemColumns.Id];
string id = this.Reader.GetId(item);
if (id == null)
{
continue;
}

DateTimeOffset updatedAt = GetUpdatedAt(item).ToUniversalTime();
DateTimeOffset updatedAt = this.Reader.GetUpdatedAt(item).GetValueOrDefault(Epoch).ToUniversalTime();
strategy.SetUpdateAt(updatedAt);

if (IsDeleted(item))
if (this.Reader.IsDeleted(item))
{
deletedIds.Add(id);
}
Expand Down Expand Up @@ -162,24 +166,6 @@ private bool EndOfResult(QueryResult result)
return cursor.Complete || result.Values.Count == 0;
}

private static bool IsDeleted(JObject item)
{
JToken deletedToken = item[MobileServiceSystemColumns.Deleted];
bool isDeleted = deletedToken != null && deletedToken.Value<bool>();
return isDeleted;
}

private static DateTimeOffset GetUpdatedAt(JObject item)
{
DateTimeOffset updatedAt = Epoch;
JToken updatedAtToken = item[MobileServiceSystemColumns.UpdatedAt];
if (updatedAtToken != null)
{
updatedAt = updatedAtToken.ToObject<DateTimeOffset?>().GetValueOrDefault(Epoch);
}
return updatedAt;
}

private async Task CreatePullStrategy()
{
bool isIncrementalSync = !String.IsNullOrEmpty(this.QueryKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public async Task PullAsync_DoesNotTriggerPush_OnUnrelatedTables_WhenThereIsOper
var item = new StringIdType() { Id = "an id", String = "what?" };
await mainTable.InsertAsync(item);

await mainTable.PullAsync(null, null, null, CancellationToken.None, "relatedTable");
await mainTable.PullAsync(null, null, null, null, CancellationToken.None, "relatedTable");

Assert.AreEqual(hijack.Requests.Count, 3); // 1 for push and 2 for pull
AssertEx.QueryEquals(hijack.Requests[0].RequestUri.AbsolutePath, "/tables/StringIdType");
Expand Down Expand Up @@ -424,7 +424,7 @@ public async Task PullAsync_TriggersPush_OnRelatedTables_WhenThereIsOperationTab
var item = new StringIdType() { Id = "abc", String = "what?" };
await mainTable.InsertAsync(item);

await mainTable.PullAsync(null, null, null, CancellationToken.None, "relatedTable");
await mainTable.PullAsync(null, null, null, null, CancellationToken.None, "relatedTable");

Assert.AreEqual(hijack.Requests.Count, 4); // 2 for push and 2 for pull
AssertEx.QueryEquals(hijack.Requests[0].RequestUri.AbsolutePath, "/tables/relatedTable");
Expand Down
Loading

0 comments on commit d0a46b6

Please sign in to comment.