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] * add table kind to distinguish operations…
Browse files Browse the repository at this point in the history
… of different type

* do not invoke sync handler for non table table operations
* make the handler optional as there is alternate way for handling sync errors
  • Loading branch information
hasankhan committed Oct 16, 2014
1 parent 5db61cd commit edc04e5
Show file tree
Hide file tree
Showing 24 changed files with 199 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Table\MobileServiceObjectReader.cs" />
<Compile Include="Table\Sync\Queue\Operations\MobileServiceTableKind.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
Expand Up @@ -234,10 +234,15 @@ public IMobileServiceTable GetTable(string tableName)
/// <param name="tableName">The name of the table.</param>
/// <returns>The table.</returns>
public IMobileServiceSyncTable GetSyncTable(string tableName)
{
return GetSyncTable(tableName, MobileServiceTableKind.Table);
}

internal MobileServiceSyncTable GetSyncTable(string tableName, MobileServiceTableKind kind)
{
ValidateTableName(tableName);

return new MobileServiceSyncTable(tableName, this);
return new MobileServiceSyncTable(tableName, kind, this);
}

/// <summary>
Expand Down Expand Up @@ -270,7 +275,7 @@ public IMobileServiceTable<T> GetTable<T>()
public IMobileServiceSyncTable<T> GetSyncTable<T>()
{
string tableName = this.SerializerSettings.ContractResolver.ResolveTableName(typeof(T));
return new MobileServiceSyncTable<T>(tableName, this);
return new MobileServiceSyncTable<T>(tableName, MobileServiceTableKind.Table, this);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,7 @@ public async Task InitializeAsync(IMobileServiceLocalStore store, IMobileService
{
throw new ArgumentNullException("store");
}
if (handler == null)
{
throw new ArgumentNullException("handler");
}
handler = handler ?? new MobileServiceSyncHandler();

this.initializeTask = new TaskCompletionSource<object>();

Expand Down Expand Up @@ -119,29 +116,29 @@ public async Task<JToken> ReadAsync(string tableName, string query)
}
}

public async Task InsertAsync(string tableName, string id, JObject item)
public async Task InsertAsync(string tableName, MobileServiceTableKind tableKind, string id, JObject item)
{
var operation = new InsertOperation(tableName, id)
var operation = new InsertOperation(tableName, tableKind, id)
{
Table = await this.GetTable(tableName)
};

await this.ExecuteOperationAsync(operation, item);
}

public async Task UpdateAsync(string tableName, string id, JObject item)
public async Task UpdateAsync(string tableName, MobileServiceTableKind tableKind, string id, JObject item)
{
var operation = new UpdateOperation(tableName, id)
var operation = new UpdateOperation(tableName, tableKind, id)
{
Table = await this.GetTable(tableName)
};

await this.ExecuteOperationAsync(operation, item);
}

public async Task DeleteAsync(string tableName, string id, JObject item)
public async Task DeleteAsync(string tableName, MobileServiceTableKind tableKind, string id, JObject item)
{
var operation = new DeleteOperation(tableName, id)
var operation = new DeleteOperation(tableName, tableKind, id)
{
Table = await this.GetTable(tableName),
Item = item // item will be deleted from store, so we need to put it in the operation queue
Expand All @@ -161,6 +158,7 @@ public async Task<JObject> LookupAsync(string tableName, string id)
/// Pulls all items that match the given query from the associated remote table.
/// </summary>
/// <param name="tableName">The name of table to pull</param>
/// <param name="tableKind">The kind of table</param>
/// <param name="queryKey">A string that uniquely identifies this query and is used to keep track of its sync state.</param>
/// <param name="query">An OData query that determines which items to
/// pull from the remote table.</param>
Expand All @@ -177,7 +175,7 @@ public async Task<JObject> LookupAsync(string tableName, string id)
/// <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, MobileServiceObjectReader reader, CancellationToken cancellationToken)
public async Task PullAsync(string tableName, MobileServiceTableKind tableKind, string queryKey, string query, MobileServiceRemoteTableOptions options, IDictionary<string, string> parameters, IEnumerable<string> relatedTables, MobileServiceObjectReader reader, CancellationToken cancellationToken)
{
await this.EnsureInitializedAsync();

Expand Down Expand Up @@ -222,33 +220,37 @@ 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 action = new PullAction(table, this, queryKey, queryDescription, parameters, relatedTables, this.opQueue, this.settings, this.Store, options, reader, cancellationToken);
var action = new PullAction(table, tableKind, 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)
public async Task PurgeAsync(string tableName, MobileServiceTableKind tableKind, string queryKey, string query, CancellationToken cancellationToken)
{
await this.EnsureInitializedAsync();

var table = await this.GetTable(tableName);
var queryDescription = MobileServiceTableQueryDescription.Parse(tableName, query);
var action = new PurgeAction(table, queryKey, queryDescription, this, this.opQueue, this.settings, this.Store, cancellationToken);
var action = new PurgeAction(table, tableKind, queryKey, queryDescription, this, this.opQueue, this.settings, this.Store, cancellationToken);
await this.ExecuteSyncAction(action);
}

public Task PushAsync(CancellationToken cancellationToken)
{
return PushAsync(cancellationToken, new string[0]);
return PushAsync(cancellationToken, MobileServiceTableKind.Table, new string[0]);
}

public async Task PushAsync(CancellationToken cancellationToken, params string[] tableNames)
public async Task PushAsync(CancellationToken cancellationToken, MobileServiceTableKind tableKind, params string[] tableNames)
{
await this.EnsureInitializedAsync();

// use empty handler if its not a standard table push
var handler = tableKind == MobileServiceTableKind.Table ? this.Handler : new MobileServiceSyncHandler();

var action = new PushAction(this.opQueue,
this.Store,
tableKind,
tableNames,
this.Handler,
handler,
this.client,
this,
cancellationToken);
Expand Down Expand Up @@ -312,7 +314,7 @@ public async Task DeferTableActionAsync(TableAction action)

try
{
await this.PushAsync(action.CancellationToken, tableNames.ToArray());
await this.PushAsync(action.CancellationToken, action.TableKind, tableNames.ToArray());
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ internal class MobileServiceSyncTable<T> : MobileServiceSyncTable, IMobileServic
private MobileServiceTableQueryProvider queryProvider;
private IMobileServiceTable<T> remoteTable;

public MobileServiceSyncTable(string tableName, MobileServiceClient client)
: base(tableName, client)
public MobileServiceSyncTable(string tableName, MobileServiceTableKind kind, MobileServiceClient client)
: base(tableName, kind, client)
{
this.remoteTable = client.GetTable<T>();
this.queryProvider = new MobileServiceTableQueryProvider(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ internal class MobileServiceSyncTable : IMobileServiceSyncTable

public string TableName { get; private set; }

public MobileServiceTableKind Kind { get; private set; }

public MobileServiceRemoteTableOptions SupportedOptions { get; set; }

public MobileServiceSyncTable(string tableName, MobileServiceClient client)
public MobileServiceSyncTable(string tableName, MobileServiceTableKind Kind, MobileServiceClient client)
{
Debug.Assert(tableName != null);
Debug.Assert(client != null);

this.MobileServiceClient = client;
this.TableName = tableName;
this.Kind = Kind;
this.syncContext = (MobileServiceSyncContext)client.SyncContext;
this.SupportedOptions = MobileServiceRemoteTableOptions.All;
}
Expand All @@ -44,19 +47,19 @@ public Task PullAsync(string queryKey, string query, IDictionary<string, string>
{
ValidateQueryKey(queryKey);

return this.syncContext.PullAsync(this.TableName, queryKey, query, this.SupportedOptions, parameters, relatedTables, reader, cancellationToken);
return this.syncContext.PullAsync(this.TableName, this.Kind, 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, null, cancellationToken);
return this.syncContext.PullAsync(this.TableName, this.Kind, queryKey, query, this.SupportedOptions, parameters, pushOtherTables ? new string[0] : null, null, cancellationToken);
}

public Task PurgeAsync(string queryKey, string query, CancellationToken cancellationToken)
{
ValidateQueryKey(queryKey);
return this.syncContext.PurgeAsync(this.TableName, queryKey, query, cancellationToken);
return this.syncContext.PurgeAsync(this.TableName, this.Kind, queryKey, query, cancellationToken);
}

public async Task<JObject> InsertAsync(JObject instance)
Expand All @@ -73,7 +76,7 @@ public async Task<JObject> InsertAsync(JObject instance)
EnsureIdIsString(id);
}

await this.syncContext.InsertAsync(this.TableName, (string)id, instance);
await this.syncContext.InsertAsync(this.TableName, this.Kind, (string)id, instance);

return instance;
}
Expand All @@ -83,15 +86,15 @@ public async Task UpdateAsync(JObject instance)
string id = EnsureIdIsString(instance);
instance = RemoveSystemPropertiesKeepVersion(instance);

await this.syncContext.UpdateAsync(this.TableName, id, instance);
await this.syncContext.UpdateAsync(this.TableName, this.Kind, id, instance);
}

public async Task DeleteAsync(JObject instance)
{
string id = EnsureIdIsString(instance);
instance = RemoveSystemPropertiesKeepVersion(instance);

await this.syncContext.DeleteAsync(this.TableName, id, instance);
await this.syncContext.DeleteAsync(this.TableName, this.Kind, id, instance);
}

public Task<JObject> LookupAsync(string id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal class PullAction : TableAction
private PullStrategy strategy;

public PullAction(MobileServiceTable table,
MobileServiceTableKind tableKind,
MobileServiceSyncContext context,
string queryKey,
MobileServiceTableQueryDescription query,
Expand All @@ -33,7 +34,7 @@ public PullAction(MobileServiceTable table,
MobileServiceRemoteTableOptions options,
MobileServiceObjectReader reader,
CancellationToken cancellationToken)
: base(table, queryKey, query, relatedTables, context, operationQueue, settings, store, cancellationToken)
: base(table, tableKind, queryKey, query, relatedTables, context, operationQueue, settings, store, cancellationToken)
{
this.options = options;
this.parameters = parameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ namespace Microsoft.WindowsAzure.MobileServices.Sync
internal class PurgeAction : TableAction
{
public PurgeAction(MobileServiceTable table,
MobileServiceTableKind tableKind,
string queryKey,
MobileServiceTableQueryDescription query,
MobileServiceSyncContext context,
OperationQueue operationQueue,
MobileServiceSyncSettingsManager settings,
IMobileServiceLocalStore store,
CancellationToken cancellationToken)
: base(table, queryKey, query, null, context, operationQueue, settings, store, cancellationToken)
: base(table, tableKind, queryKey, query, null, context, operationQueue, settings, store, cancellationToken)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ internal class PushAction : SyncAction
private MobileServiceClient client;
private MobileServiceSyncContext context;
private IEnumerable<string> tableNames;
private MobileServiceTableKind tableKind;

public PushAction(OperationQueue operationQueue,
IMobileServiceLocalStore store,
MobileServiceTableKind tableKind,
IEnumerable<string> tableNames,
IMobileServiceSyncHandler syncHandler,
MobileServiceClient client,
MobileServiceSyncContext context,
CancellationToken cancellationToken)
: base(operationQueue, store, cancellationToken)
{
this.tableKind = tableKind;
this.tableNames = tableNames;
this.client = client;
this.syncHandler = syncHandler;
Expand Down Expand Up @@ -124,7 +127,7 @@ private async Task FinalizePush(OperationBatch batch, MobileServicePushStatus ba

private async Task ExecuteAllOperationsAsync(OperationBatch batch)
{
MobileServiceTableOperation operation = await this.OperationQueue.PeekAsync(0, this.tableNames);
MobileServiceTableOperation operation = await this.OperationQueue.PeekAsync(0, this.tableKind, this.tableNames);

// keep taking out operations and executing them until queue is empty or operation finds the bookmark or batch is aborted
while (operation != null)
Expand All @@ -143,7 +146,7 @@ private async Task ExecuteAllOperationsAsync(OperationBatch batch)
}

// get next operation
operation = await this.OperationQueue.PeekAsync(operation.Sequence, this.tableNames);
operation = await this.OperationQueue.PeekAsync(operation.Sequence, this.tableKind, this.tableNames);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ internal abstract class TableAction : SyncAction
protected string QueryKey { get; private set; }
protected MobileServiceTableQueryDescription Query { get; private set; }
public MobileServiceTable Table { get; private set; }
public MobileServiceTableKind TableKind { get; private set; }

protected MobileServiceSyncSettingsManager Settings { get; private set; }

protected abstract bool CanDeferIfDirty { get; }
public IEnumerable<string> RelatedTables { get; set; }

public TableAction(MobileServiceTable table,
MobileServiceTableKind tableKind,
string queryKey,
MobileServiceTableQueryDescription query,
IEnumerable<string> relatedTables,
Expand All @@ -38,6 +41,7 @@ public TableAction(MobileServiceTable table,
: base(operationQueue, store, cancellationToken)
{
this.Table = table;
this.TableKind = tableKind;
this.QueryKey = queryKey;
this.Query = query;
this.RelatedTables = relatedTables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ public OperationQueue(IMobileServiceLocalStore store)
this.store = store;
}

public async virtual Task<MobileServiceTableOperation> PeekAsync(long prevSequenceId, IEnumerable<string> tableNames)
public async virtual Task<MobileServiceTableOperation> PeekAsync(long prevSequenceId, MobileServiceTableKind tableKind, IEnumerable<string> tableNames)
{
MobileServiceTableQueryDescription query = CreateQuery();

query.Filter = Compare(BinaryOperatorKind.GreaterThan, "sequence", prevSequenceId);
var tableKindNode = Compare(BinaryOperatorKind.Equal, "tableKind", (int)tableKind);
var sequenceNode = Compare(BinaryOperatorKind.GreaterThan, "sequence", prevSequenceId);

query.Filter = new BinaryOperatorNode(BinaryOperatorKind.And, tableKindNode, sequenceNode);

if (tableNames != null && tableNames.Any())
{
BinaryOperatorNode nameInList = tableNames.Select(t => Compare(BinaryOperatorKind.Equal, "tableName", t))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ protected override bool SerializeItemToQueue
get { return true; } // delete should save the item in queue since store copy is deleted right away with delete operation
}

public DeleteOperation(string tableName, string itemId)
: base(tableName, itemId)
public DeleteOperation(string tableName, MobileServiceTableKind tableKind, string itemId)
: base(tableName, tableKind, itemId)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public override MobileServiceTableOperationKind Kind
get { return MobileServiceTableOperationKind.Insert; }
}

public InsertOperation(string tableName, string itemId)
: base(tableName, itemId)
public InsertOperation(string tableName, MobileServiceTableKind tableKind, string itemId)
: base(tableName, tableKind, itemId)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------

namespace Microsoft.WindowsAzure.MobileServices.Sync
{
/// <summary>
/// Enumeration for kinds of tables.
/// </summary>
internal enum MobileServiceTableKind
{
/// <summary>
/// Standard Table
/// </summary>
Table = 0
}
}
Loading

0 comments on commit edc04e5

Please sign in to comment.