public PullStrategy(MobileServiceTableQueryDescription query, PullCursor cursor, MobileServiceRemoteTableOptions options, PullOptions pullOptions) { this.Query = query; this.Cursor = cursor; this.PullOptions = pullOptions ?? new PullOptions(); this.SupportsSkip = options.HasFlag(MobileServiceRemoteTableOptions.Skip); this.SupportsTop = options.HasFlag(MobileServiceRemoteTableOptions.Top); }
public IncrementalPullStrategy(MobileServiceTable table, MobileServiceTableQueryDescription query, string queryId, MobileServiceSyncSettingsManager settings, PullCursor cursor, MobileServiceRemoteTableOptions options, PullOptions pullOptions) : base(query, cursor, options, pullOptions) { this.table = table; this.originalFilter = query.Filter; this.queryId = queryId; this.settings = settings; this.ordered = options.HasFlag(MobileServiceRemoteTableOptions.OrderBy); }
public PullAction(MobileServiceTable table, MobileServiceTableKind tableKind, MobileServiceSyncContext context, string queryId, MobileServiceTableQueryDescription query, IDictionary<string, string> parameters, IEnumerable<string> relatedTables, OperationQueue operationQueue, MobileServiceSyncSettingsManager settings, IMobileServiceLocalStore store, MobileServiceRemoteTableOptions options, PullOptions pullOptions, MobileServiceObjectReader reader, CancellationToken cancellationToken) : base(table, tableKind, queryId, query, relatedTables, context, operationQueue, settings, store, cancellationToken) { this.options = options; this.parameters = parameters; this.cursor = new PullCursor(query); this.pullOptions = pullOptions; this.Reader = reader ?? new MobileServiceObjectReader(); }
public PullAction(MobileServiceTable table, MobileServiceTableKind tableKind, MobileServiceSyncContext context, string queryId, MobileServiceTableQueryDescription query, IDictionary <string, string> parameters, IEnumerable <string> relatedTables, OperationQueue operationQueue, MobileServiceSyncSettingsManager settings, IMobileServiceLocalStore store, MobileServiceRemoteTableOptions options, PullOptions pullOptions, MobileServiceObjectReader reader, CancellationToken cancellationToken) : base(table, tableKind, queryId, query, relatedTables, context, operationQueue, settings, store, cancellationToken) { this.options = options; this.parameters = parameters; this.cursor = new PullCursor(query); this.pullOptions = pullOptions; this.Reader = reader ?? new MobileServiceObjectReader(); }
public Task PullAsync(string queryId, string query, IDictionary<string, string> parameters, MobileServiceObjectReader reader, CancellationToken cancellationToken, PullOptions pullOptions, params string[] relatedTables) { ValidateQueryId(queryId); return this.syncContext.PullAsync(this.TableName, this.Kind, queryId, query, this.SupportedOptions, parameters, relatedTables, reader, cancellationToken, pullOptions); }
/// <summary> /// 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="queryId">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> /// <param name="options">An instance of <see cref="MobileServiceRemoteTableOptions"/></param> /// <param name="parameters">A dictionary of user-defined parameters and values to include in /// the request URI query string.</param> /// <param name="relatedTables"> /// 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> /// <param name="pullOptions"> /// PullOptions that determine how to pull data from the remote table /// </param> /// <returns> /// A task that completes when pull operation has finished. /// </returns> public async Task PullAsync(string tableName, MobileServiceTableKind tableKind, string queryId, string query, MobileServiceRemoteTableOptions options, IDictionary<string, string> parameters, IEnumerable<string> relatedTables, MobileServiceObjectReader reader, CancellationToken cancellationToken, PullOptions pullOptions) { await this.EnsureInitializedAsync(); if (parameters != null) { if (parameters.Keys.Any(k => k.Equals(MobileServiceTable.IncludeDeletedParameterName, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("The key '{0}' is reserved and cannot be specified as a query parameter.".FormatInvariant(MobileServiceTable.IncludeDeletedParameterName)); } } var table = await this.GetTable(tableName); var queryDescription = MobileServiceTableQueryDescription.Parse(this.client.MobileAppUri, tableName, query); // local schema should be same as remote schema otherwise push can't function if (queryDescription.Selection.Any() || queryDescription.Projections.Any()) { throw new ArgumentException("Pull query with select clause is not supported.", "query"); } bool isIncrementalSync = !String.IsNullOrEmpty(queryId); if (isIncrementalSync) { if (queryDescription.Ordering.Any()) { throw new ArgumentException("Incremental pull query must not have orderby clause.", "query"); } if (queryDescription.Top.HasValue || queryDescription.Skip.HasValue) { throw new ArgumentException("Incremental pull query must not have skip or top specified.", "query"); } } if (!options.HasFlag(MobileServiceRemoteTableOptions.OrderBy) && queryDescription.Ordering.Any()) { throw new ArgumentException("The supported table options does not include orderby.", "query"); } if (!options.HasFlag(MobileServiceRemoteTableOptions.Skip) && queryDescription.Skip.HasValue) { throw new ArgumentException("The supported table options does not include skip.", "query"); } if (!options.HasFlag(MobileServiceRemoteTableOptions.Top) && queryDescription.Top.HasValue) { throw new ArgumentException("The supported table options does not include top.", "query"); } // let us not burden the server to calculate the count when we don't need it for pull queryDescription.IncludeTotalCount = false; using (var store = StoreChangeTrackerFactory.CreateTrackedStore(this.Store, StoreOperationSource.ServerPull, this.storeTrackingOptions, this.client.EventManager, this.settings)) { var action = new PullAction(table, tableKind, this, queryId, queryDescription, parameters, relatedTables, this.opQueue, this.settings, store, options, pullOptions, reader, cancellationToken); await this.ExecuteSyncAction(action); } }
/// <summary> /// 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="queryId">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> /// <param name="options">An instance of <see cref="MobileServiceRemoteTableOptions"/></param> /// <param name="parameters">A dictionary of user-defined parameters and values to include in /// the request URI query string.</param> /// <param name="relatedTables"> /// 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> /// <param name="pullOptions"> /// PullOptions that determine how to pull data from the remote table /// </param> /// <returns> /// A task that completes when pull operation has finished. /// </returns> public async Task PullAsync(string tableName, MobileServiceTableKind tableKind, string queryId, string query, MobileServiceRemoteTableOptions options, IDictionary <string, string> parameters, IEnumerable <string> relatedTables, MobileServiceObjectReader reader, CancellationToken cancellationToken, PullOptions pullOptions) { await this.EnsureInitializedAsync(); if (parameters != null) { if (parameters.Keys.Any(k => k.Equals(MobileServiceTable.IncludeDeletedParameterName, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("The key '{0}' is reserved and cannot be specified as a query parameter.".FormatInvariant(MobileServiceTable.IncludeDeletedParameterName)); } } var table = await this.GetTable(tableName); var queryDescription = MobileServiceTableQueryDescription.Parse(this.client.MobileAppUri, tableName, query); // local schema should be same as remote schema otherwise push can't function if (queryDescription.Selection.Any() || queryDescription.Projections.Any()) { throw new ArgumentException("Pull query with select clause is not supported.", "query"); } bool isIncrementalSync = !String.IsNullOrEmpty(queryId); if (isIncrementalSync) { if (queryDescription.Ordering.Any()) { throw new ArgumentException("Incremental pull query must not have orderby clause.", "query"); } if (queryDescription.Top.HasValue || queryDescription.Skip.HasValue) { throw new ArgumentException("Incremental pull query must not have skip or top specified.", "query"); } } if (!options.HasFlag(MobileServiceRemoteTableOptions.OrderBy) && queryDescription.Ordering.Any()) { throw new ArgumentException("The supported table options does not include orderby.", "query"); } if (!options.HasFlag(MobileServiceRemoteTableOptions.Skip) && queryDescription.Skip.HasValue) { throw new ArgumentException("The supported table options does not include skip.", "query"); } if (!options.HasFlag(MobileServiceRemoteTableOptions.Top) && queryDescription.Top.HasValue) { throw new ArgumentException("The supported table options does not include top.", "query"); } // let us not burden the server to calculate the count when we don't need it for pull queryDescription.IncludeTotalCount = false; using (var store = StoreChangeTrackerFactory.CreateTrackedStore(this.Store, StoreOperationSource.ServerPull, this.storeTrackingOptions, this.client.EventManager, this.settings)) { var action = new PullAction(table, tableKind, this, queryId, queryDescription, parameters, relatedTables, this.opQueue, this.settings, store, options, pullOptions, reader, cancellationToken); await this.ExecuteSyncAction(action); } }
public async Task PullAsync_DefaultsTo50_IfGreaterThanMaxPageSize() { var hijack = new TestHttpHandler(); hijack.AddResponseContent("[{\"id\":\"abc\",\"String\":\"Hey\"},{\"id\":\"def\",\"String\":\"How\"}]"); // first page hijack.AddResponseContent("[]"); // end of the list var store = new MobileServiceLocalStoreMock(); IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); MobileAppUriValidator mobileAppUriValidator = new MobileAppUriValidator(service); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); IMobileServiceSyncTable<ToDoWithStringId> table = service.GetSyncTable<ToDoWithStringId>(); Assert.IsFalse(store.TableMap.ContainsKey("stringId_test_table")); var pullOptions = new PullOptions { MaxPageSize = 50, }; await table.PullAsync(null, table.Take(51), pullOptions); Assert.AreEqual(store.TableMap["stringId_test_table"].Count, 2); AssertEx.MatchUris(hijack.Requests, mobileAppUriValidator.GetTableUri("stringId_test_table?$skip=0&$top=50&__includeDeleted=true"), mobileAppUriValidator.GetTableUri("stringId_test_table?$skip=2&$top=49&__includeDeleted=true")); }
public Task PullAsync(string queryId, string query, IDictionary <string, string> parameters, bool pushOtherTables, CancellationToken cancellationToken, PullOptions pullOptions) { ValidateQueryId(queryId); return(this.syncContext.PullAsync(this.TableName, this.Kind, queryId, query, this.SupportedOptions, parameters, pushOtherTables ? new string[0] : null, null, cancellationToken, pullOptions)); }
public Task PullAsync(string queryId, string query, IDictionary <string, string> parameters, MobileServiceObjectReader reader, CancellationToken cancellationToken, PullOptions pullOptions, params string[] relatedTables) { ValidateQueryId(queryId); return(this.syncContext.PullAsync(this.TableName, this.Kind, queryId, query, this.SupportedOptions, parameters, relatedTables, reader, cancellationToken, pullOptions)); }
public async Task PullAsync_Incremental_PageSize() { var hijack = new TestHttpHandler(); hijack.OnSendingRequest = req => { return Task.FromResult(req); }; hijack.AddResponseContent(@"[{""id"":""abc"",""String"":""Hey""}]"); hijack.AddResponseContent("[]"); // last page var store = new MobileServiceLocalStoreMock(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); IMobileServiceSyncTable<ToDoWithStringId> table = service.GetSyncTable<ToDoWithStringId>(); PullOptions pullOptions = new PullOptions { MaxPageSize = 10 }; await table.PullAsync("items", table.CreateQuery(), pullOptions: pullOptions); AssertEx.MatchUris(hijack.Requests, string.Format("http://www.test.com/tables/stringId_test_table?$filter=(__updatedAt ge datetimeoffset'1970-01-01T00:00:00.0000000%2B00:00')&$orderby=__updatedAt&$skip=0&$top={0}&__includeDeleted=true&__systemproperties=__updatedAt%2C__version%2C__deleted", pullOptions.MaxPageSize), string.Format("http://www.test.com/tables/stringId_test_table?$filter=(__updatedAt ge datetimeoffset'1970-01-01T00:00:00.0000000%2B00:00')&$orderby=__updatedAt&$skip=1&$top={0}&__includeDeleted=true&__systemproperties=__updatedAt%2C__version%2C__deleted", pullOptions.MaxPageSize)); }
public async Task PullAsync_DefaultsTo50_IfGreaterThanMaxPageSize() { var hijack = new TestHttpHandler(); hijack.AddResponseContent("[{\"id\":\"abc\",\"String\":\"Hey\"},{\"id\":\"def\",\"String\":\"How\"}]"); // first page hijack.AddResponseContent("[]"); // end of the list var store = new MobileServiceLocalStoreMock(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); IMobileServiceSyncTable<ToDoWithStringId> table = service.GetSyncTable<ToDoWithStringId>(); Assert.IsFalse(store.TableMap.ContainsKey("stringId_test_table")); var pullOptions = new PullOptions { MaxPageSize = 50, }; await table.PullAsync(null, table.Take(51), pullOptions); Assert.AreEqual(store.TableMap["stringId_test_table"].Count, 2); AssertEx.MatchUris(hijack.Requests, "http://www.test.com/tables/stringId_test_table?$skip=0&$top=50&__includeDeleted=true&__systemproperties=__version%2C__deleted", "http://www.test.com/tables/stringId_test_table?$skip=2&$top=49&__includeDeleted=true&__systemproperties=__version%2C__deleted"); }
public Task PullAsync(string queryId, string query, IDictionary<string, string> parameters, bool pushOtherTables, CancellationToken cancellationToken, PullOptions pullOptions) { ValidateQueryId(queryId); return this.syncContext.PullAsync(this.TableName, this.Kind, queryId, query, this.SupportedOptions, parameters, pushOtherTables ? new string[0] : null, null, cancellationToken, pullOptions); }
public Task PullAsync <U>(string queryId, IMobileServiceTableQuery <U> query, bool pushOtherTables, CancellationToken cancellationToken, PullOptions pullOptions) { if (query == null) { throw new ArgumentNullException("query"); } string queryString = this.queryProvider.ToODataString(query); return(this.PullAsync(queryId, queryString, query.Parameters, pushOtherTables, cancellationToken, pullOptions)); }
public Task PullAsync <U>(string queryId, IMobileServiceTableQuery <U> query, bool pushOtherTables, CancellationToken cancellationToken, PullOptions pullOptions) { Arguments.IsNotNull(query, nameof(query)); string queryString = this.queryProvider.ToODataString(query); return(this.PullAsync(queryId, queryString, query.Parameters, pushOtherTables, cancellationToken, pullOptions)); }