/// <summary>
        /// Load more items asynchronously.
        /// Controls which support incremental loading on such as GridView on Windows 8
        /// call this method automatically.
        /// In other cases you should call this method yourself.
        /// </summary>
        /// <param name="token">
        /// The cancellation token to be used to cancel the task.
        /// </param>
        /// <param name="count">
        /// The number of items to load.
        /// This parameter overrides the pageSize specified in the constructore.
        /// </param>
        /// <returns>The result of loading the items.</returns>
        public async Task <int> LoadMoreItemsAsync(CancellationToken token, int count = 0)
        {
            if (busy)
            {
                throw new InvalidOperationException("Only one operation in flight at a time");
            }
            busy = true;

            try
            {
                //check for cancellation
                if (token.IsCancellationRequested)
                {
                    throw new OperationCanceledException();
                }

                IMobileServiceTableQuery <TTable> query = this.query;
                if (count == 0)
                {
                    count = PageSize;
                }
                //if still 0, PageSize was 0
                if (count != 0)
                {
                    query = query.Skip(itemsReceived).Take(count);
                }
                else
                {
                    //disable paging if pagesize is 0
                    this.HasMoreItems = false;
                }

                int results = await this.ProcessQueryAsync(token, query);

                if (results == 0)
                {
                    this.HasMoreItems = false;
                }
                else
                {
                    this.itemsReceived += results;
                }
                //safe conversion since there can't be negative results
                return(results);
            }
            catch
            {
                // in case of error don't automatically try again
                this.HasMoreItems = false;
                throw;
            }
            finally
            {
                busy = false;
            }
        }
Exemple #2
0
        private async void RefreshQueryAsync()
        {
            // Temporarily disable the next/prev commands until this query finishes
            NextCommand.IsEnabled = false;
            PrevCommand.IsEnabled = false;
            List <Profile> profiles = await query.Skip(currentPage *profileCountPerPage).ToListAsync();

            totalCount = ((ITotalCountProvider)profiles).TotalCount;
            Users.Clear();
            Users.AddRange(profiles);
            EnableDisablePaging();
        }
        private async Task CreateQueryTest <MovieType, TExpectedException>(
            string name, Expression <Func <MovieType, bool> > whereClause,
            int?top = null, int?skip = null, OrderByClause[] orderBy = null,
            Expression <Func <MovieType, string> > selectExpression = null, bool?includeTotalCount = null,
            string odataExpression             = null, bool useStringIdTable = false,
            Func <MovieType, bool> whereLambda = null)
            where MovieType : class, IMovie
            where TExpectedException : Exception
        {
            Log("### Executing {0}.", name);
            if (whereClause == null && whereLambda != null)
            {
                Assert.Fail("The argument 'whereLambda' is optional and can only be specified if 'whereClause' is also specified.");
            }

            try
            {
                var table = this.GetClient().GetTable <MovieType>();
                IEnumerable <MovieType> readMovies          = null;
                IEnumerable <string>    readProjectedMovies = null;

                if (odataExpression == null)
                {
                    IMobileServiceTableQuery <MovieType> query         = null;
                    IMobileServiceTableQuery <string>    selectedQuery = null;

                    if (whereClause != null)
                    {
                        query = table.Where(whereClause);
                    }

                    if (orderBy != null)
                    {
                        if (query == null)
                        {
                            query = table.Where(m => m.Duration == m.Duration);
                        }

                        query = ApplyOrdering(query, orderBy);
                    }

                    if (top.HasValue)
                    {
                        query = query == null?table.Take(top.Value) : query.Take(top.Value);
                    }

                    if (skip.HasValue)
                    {
                        query = query == null?table.Skip(skip.Value) : query.Skip(skip.Value);
                    }

                    if (selectExpression != null)
                    {
                        selectedQuery = query == null?table.Select(selectExpression) : query.Select(selectExpression);
                    }

                    if (includeTotalCount.HasValue)
                    {
                        query = query.IncludeTotalCount();
                    }

                    if (selectedQuery == null)
                    {
                        // Both ways of querying should be equivalent, so using both with equal probability here.
                        // TODO: Make it deterministic
                        var tickCount = Environment.TickCount;
                        if ((tickCount % 2) == 0)
                        {
                            Log("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync");
                            readMovies = await query.ToEnumerableAsync();
                        }
                        else
                        {
                            Log("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)");
                            readMovies = await table.ReadAsync(query);
                        }
                    }
                    else
                    {
                        readProjectedMovies = await selectedQuery.ToEnumerableAsync();
                    }
                }
                else
                {
                    Log("Using the OData query directly");
                    JToken result = await table.ReadAsync(odataExpression);

                    readMovies = result.ToObject <IEnumerable <MovieType> >();
                }

                long actualTotalCount = -1;
                ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider);
                if (totalCountProvider != null)
                {
                    actualTotalCount = totalCountProvider.TotalCount;
                }

                IEnumerable <MovieType> expectedData;
                if (useStringIdTable)
                {
                    var movies = QueryTestData.TestMovies();
                    expectedData = new MovieType[movies.Length];
                    for (var i = 0; i < movies.Length; i++)
                    {
                        ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i];
                    }
                }
                else
                {
                    expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s);
                }

                // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees,
                // in which case we allow the caller to provide a lambda directly and we use it instead of
                // compiling the expression tree.
                if (whereLambda != null)
                {
                    expectedData = expectedData.Where(whereLambda);
                }
                else if (whereClause != null)
                {
                    expectedData = expectedData.Where(whereClause.Compile());
                }

                long expectedTotalCount = -1;
                if (includeTotalCount.HasValue && includeTotalCount.Value)
                {
                    expectedTotalCount = expectedData.Count();
                }

                if (orderBy != null)
                {
                    expectedData = ApplyOrdering(expectedData, orderBy);
                }

                if (skip.HasValue)
                {
                    expectedData = expectedData.Skip(skip.Value);
                }

                if (top.HasValue)
                {
                    expectedData = expectedData.Take(top.Value);
                }

                if (includeTotalCount.HasValue)
                {
                    if (expectedTotalCount != actualTotalCount)
                    {
                        Log("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount);
                        Assert.Fail("");
                        return;
                    }
                }

                List <string> errors = new List <string>();
                bool          expectedDataIsSameAsReadData;

                if (selectExpression != null)
                {
                    string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray();
                    expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors);
                }
                else
                {
                    expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors);
                }

                if (!expectedDataIsSameAsReadData)
                {
                    foreach (var error in errors)
                    {
                        Log(error);
                    }

                    Log("Expected data is different");
                    Assert.Fail("");
                    return;
                }
                else
                {
                    if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown))
                    {
                        return;
                    }
                    else
                    {
                        Log("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName);
                        Assert.Fail("");
                        return;
                    }
                }
            }
            catch (TExpectedException ex)
            {
                Log("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message);
                return;
            }
        }
Exemple #4
0
        private static ZumoTest CreateQueryTest <TExpectedException>(
            string name, Expression <Func <Movie, bool> > whereClause,
            int?top = null, int?skip = null, OrderByClause[] orderBy = null,
            Expression <Func <Movie, string> > selectExpression = null, bool?includeTotalCount = null,
            string odataExpression = null)
            where TExpectedException : Exception
        {
            return(new ZumoTest(name, async delegate(ZumoTest test)
            {
                try
                {
                    var table = ZumoTestGlobals.Instance.Client.GetTable <Movie>();
                    IEnumerable <Movie> readMovies = null;
                    IEnumerable <string> readProjectedMovies = null;

                    if (odataExpression == null)
                    {
                        IMobileServiceTableQuery <Movie> query = null;
                        IMobileServiceTableQuery <string> selectedQuery = null;

                        if (whereClause != null)
                        {
                            query = table.Where(whereClause);
                        }

                        if (orderBy != null)
                        {
                            if (query == null)
                            {
                                query = table.Where(m => m.Duration == m.Duration);
                            }

                            query = ApplyOrdering(query, orderBy);
                        }

                        if (top.HasValue)
                        {
                            query = query == null ? table.Take(top.Value) : query.Take(top.Value);
                        }

                        if (skip.HasValue)
                        {
                            query = query == null ? table.Skip(skip.Value) : query.Skip(skip.Value);
                        }

                        if (selectExpression != null)
                        {
                            selectedQuery = query == null ? table.Select(selectExpression) : query.Select(selectExpression);
                        }

                        if (includeTotalCount.HasValue)
                        {
                            query = query.IncludeTotalCount();
                        }

                        if (selectedQuery == null)
                        {
                            // Both ways of querying should be equivalent, so using both with equal probability here.
                            var tickCount = Environment.TickCount;
                            if ((tickCount % 2) == 0)
                            {
                                test.AddLog("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync");
                                readMovies = await query.ToEnumerableAsync();
                            }
                            else
                            {
                                test.AddLog("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)");
                                readMovies = await table.ReadAsync(query);
                            }
                        }
                        else
                        {
                            readProjectedMovies = await selectedQuery.ToEnumerableAsync();
                        }
                    }
                    else
                    {
                        test.AddLog("Using the OData query directly");
                        JToken result = await table.ReadAsync(odataExpression);
                        readMovies = result.ToObject <IEnumerable <Movie> >();
                    }

                    long actualTotalCount = -1;
                    ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider);
                    if (totalCountProvider != null)
                    {
                        actualTotalCount = totalCountProvider.TotalCount;
                    }

                    IEnumerable <Movie> expectedData = ZumoQueryTestData.AllMovies;
                    if (whereClause != null)
                    {
                        expectedData = expectedData.Where(whereClause.Compile());
                    }

                    long expectedTotalCount = -1;
                    if (includeTotalCount.HasValue && includeTotalCount.Value)
                    {
                        expectedTotalCount = expectedData.Count();
                    }

                    if (orderBy != null)
                    {
                        expectedData = ApplyOrdering(expectedData, orderBy);
                    }

                    if (skip.HasValue)
                    {
                        expectedData = expectedData.Skip(skip.Value);
                    }

                    if (top.HasValue)
                    {
                        expectedData = expectedData.Take(top.Value);
                    }


                    if (includeTotalCount.HasValue)
                    {
                        if (expectedTotalCount != actualTotalCount)
                        {
                            test.AddLog("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount);
                            return false;
                        }
                    }

                    List <string> errors = new List <string>();
                    bool expectedDataIsSameAsReadData;

                    if (selectExpression != null)
                    {
                        string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray();
                        expectedDataIsSameAsReadData = Util.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors);
                    }
                    else
                    {
                        expectedDataIsSameAsReadData = Util.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors);
                    }

                    if (!expectedDataIsSameAsReadData)
                    {
                        foreach (var error in errors)
                        {
                            test.AddLog(error);
                        }

                        test.AddLog("Expected data is different");
                        return false;
                    }
                    else
                    {
                        if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown))
                        {
                            return true;
                        }
                        else
                        {
                            test.AddLog("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName);
                            return false;
                        }
                    }
                }
                catch (TExpectedException ex)
                {
                    test.AddLog("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message);
                    return true;
                }
            }));
        }
        private async Task CreateQueryTest <MovieType, TExpectedException>(
            string name, Expression <Func <MovieType, bool> > whereClause,
            int?top = null, int?skip = null, OrderByClause[] orderBy = null,
            Expression <Func <MovieType, string> > selectExpression = null, bool?includeTotalCount = null,
            string odataExpression             = null, bool useStringIdTable = false,
            Func <MovieType, bool> whereLambda = null)
            where MovieType : class, IMovie
            where TExpectedException : Exception
        {
            Assert.False(whereClause == null && whereLambda != null);

            try
            {
                var table = this.GetClient().GetTable <MovieType>();
                IEnumerable <MovieType> readMovies          = null;
                IEnumerable <string>    readProjectedMovies = null;

                if (odataExpression == null)
                {
                    IMobileServiceTableQuery <MovieType> query         = null;
                    IMobileServiceTableQuery <string>    selectedQuery = null;

                    if (whereClause != null)
                    {
                        query = table.Where(whereClause);
                    }

                    if (orderBy != null)
                    {
                        if (query == null)
                        {
                            query = table.Where(m => m.Duration == m.Duration);
                        }

                        query = ApplyOrdering(query, orderBy);
                    }

                    if (top.HasValue)
                    {
                        query = query == null?table.Take(top.Value) : query.Take(top.Value);
                    }

                    if (skip.HasValue)
                    {
                        query = query == null?table.Skip(skip.Value) : query.Skip(skip.Value);
                    }

                    if (selectExpression != null)
                    {
                        selectedQuery = query == null?table.Select(selectExpression) : query.Select(selectExpression);
                    }

                    if (includeTotalCount.HasValue)
                    {
                        query = query.IncludeTotalCount();
                    }

                    if (selectedQuery == null)
                    {
                        // Both ways of querying should be equivalent, so using both with equal probability here.
                        // TODO: Make it deterministic
                        var tickCount = Environment.TickCount;
                        if ((tickCount % 2) == 0)
                        {
                            readMovies = await query.ToEnumerableAsync();
                        }
                        else
                        {
                            readMovies = await table.ReadAsync(query);
                        }
                    }
                    else
                    {
                        readProjectedMovies = await selectedQuery.ToEnumerableAsync();
                    }
                }
                else
                {
                    JToken result = await table.ReadAsync(odataExpression);

                    readMovies = result.ToObject <IEnumerable <MovieType> >();
                }

                long actualTotalCount = -1;
#pragma warning disable CS0618 // Type or member is obsolete
                ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider);
#pragma warning restore CS0618 // Type or member is obsolete
                if (totalCountProvider != null)
                {
                    actualTotalCount = totalCountProvider.TotalCount;
                }

                IEnumerable <MovieType> expectedData;
                if (useStringIdTable)
                {
                    var movies = QueryTestData.TestMovies();
                    expectedData = new MovieType[movies.Length];
                    for (var i = 0; i < movies.Length; i++)
                    {
                        ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i];
                    }
                }
                else
                {
                    expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s);
                }

                // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees,
                // in which case we allow the caller to provide a lambda directly and we use it instead of
                // compiling the expression tree.
                if (whereLambda != null)
                {
                    expectedData = expectedData.Where(whereLambda);
                }
                else if (whereClause != null)
                {
                    expectedData = expectedData.Where(whereClause.Compile());
                }

                long expectedTotalCount = -1;
                if (includeTotalCount.HasValue && includeTotalCount.Value)
                {
                    expectedTotalCount = expectedData.Count();
                }

                if (orderBy != null)
                {
                    expectedData = ApplyOrdering(expectedData, orderBy);
                }

                if (skip.HasValue)
                {
                    expectedData = expectedData.Skip(skip.Value);
                }

                if (top.HasValue)
                {
                    expectedData = expectedData.Take(top.Value);
                }

                if (includeTotalCount.HasValue)
                {
                    Assert.Equal(expectedTotalCount, actualTotalCount);
                }

                List <string> errors = new List <string>();
                bool          expectedDataIsSameAsReadData;

                if (selectExpression != null)
                {
                    string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray();
                    expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors);
                }
                else
                {
                    expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors);
                }

                Assert.True(expectedDataIsSameAsReadData);

                if (typeof(TExpectedException) != typeof(ExceptionTypeWhichWillNeverBeThrown))
                {
                    Assert.True(false, "Test should have failed");
                    return;
                }
            }
            catch (TExpectedException)
            {
                return;
            }
        }
Exemple #6
0
 public IAsyncQuery <T> Skip(int count)
 {
     return(new AsyncQuery <T>(from.Skip(count)));
 }
        /// <summary>
        /// Load more items asynchronously.
        /// Controls which support incremental loading on such as GridView on Windows 8
        /// call this method automatically.
        /// In other cases you should call this method yourself.
        /// </summary>
        /// <param name="token">
        /// The cancellation token to be used to cancel the task.
        /// </param>
        /// <param name="count">
        /// The number of items to load.
        /// This parameter overrides the pageSize specified in the constructor.
        /// </param>
        /// <returns>The result of loading the items.</returns>
        public async Task <int> LoadMoreItemsAsync(CancellationToken token, int count = 0)
        {
            if (busy)
            {
                throw new InvalidOperationException(Resources.MobileServiceCollection_LoadInProcess);
            }

            busy = true;

            EventHandler loadingItems = LoadingItems;

            if (loadingItems != null)
            {
                loadingItems(this, new EventArgs());
            }

            int results = 0;

            try
            {
                //check for cancellation
                if (token.IsCancellationRequested)
                {
                    throw new OperationCanceledException();
                }

                IMobileServiceTableQuery <TTable> query = this.query;
                if (count == 0)
                {
                    count = PageSize;
                }
                //if still 0, PageSize was 0
                if (count != 0)
                {
                    query = query.Skip(itemsReceived).Take(count);
                }
                else
                {
                    //disable paging if pagesize is 0
                    this.HasMoreItems = false;
                }

                results = await this.ProcessQueryAsync(token, query);

                if (results == 0)
                {
                    this.HasMoreItems = false;
                }
                else
                {
                    this.itemsReceived += results;
                }
                //safe conversion since there can't be negative results
                return(results);
            }
            catch
            {
                // in case of error don't automatically try again
                this.HasMoreItems = false;
                throw;
            }
            finally
            {
                busy = false;

                EventHandler <LoadingCompleteEventArgs> loadingComplete = LoadingComplete;
                if (loadingComplete != null)
                {
                    loadingComplete(this, new LoadingCompleteEventArgs()
                    {
                        TotalItemsLoaded = results
                    });
                }
            }
        }