예제 #1
0
        public QueryCacheItem GetQueryCacheItem(string collectionName, string query, string lastRequest)
        {
            lock (DBConnectionSync)
            {
                QueryCacheItem result = null;

                if (!TableExists <QueryCacheItem>(DBConnectionSync))
                {
                    DBConnectionSync.CreateTable <QueryCacheItem>();
                }
                else
                {
                    var items = DBConnectionSync.Table <QueryCacheItem>().Where(item => item.collectionName == collectionName && item.query == query);
                    if (items.Count() == 1)
                    {
                        foreach (QueryCacheItem item in items)
                        {
                            result = item;
                        }
                    }
                }

                return(result);
            }
        }
예제 #2
0
        public bool DeleteQueryCacheItem(QueryCacheItem item)
        {
            lock (DBConnectionSync)
            {
                bool success = false;

                if (TableExists <QueryCacheItem>(DBConnectionSync))
                {
                    int result = DBConnectionSync.Delete(item);

                    if (result != 0)
                    {
                        success = true;
                    }
                }

                return(success);
            }
        }
예제 #3
0
        public bool SetQueryCacheItem(QueryCacheItem item)
        {
            lock (DBConnectionSync)
            {
                bool success = false;

                if (!TableExists <QueryCacheItem>(DBConnectionSync))
                {
                    DBConnectionSync.CreateTable <QueryCacheItem>();
                }

                int result = DBConnectionSync.InsertOrReplace(item);
                if (result != 0)
                {
                    success = true;
                }

                return(success);
            }
        }
예제 #4
0
        private async Task <NetworkReadResponse <T> > PerformNetworkInitialDeltaGet(string mongoQuery, QueryCacheItem queryCacheItem = null)
        {
            var      getResult = Client.NetworkFactory.buildGetRequest <T>(Collection, mongoQuery);
            List <T> results   = await getResult.ExecuteAsync().ConfigureAwait(false);

            Cache.Clear(Query?.Expression);
            Cache.RefreshCache(results);
            string lastRequestTime = getResult.RequestStartTime;

            if (queryCacheItem != null && !string.IsNullOrEmpty(queryCacheItem.lastRequest))
            {
                queryCacheItem.lastRequest = getResult.RequestStartTime;
            }
            else
            {
                queryCacheItem = new QueryCacheItem(Collection, mongoQuery, lastRequestTime);
            }

            Client.CacheManager.SetQueryCacheItem(queryCacheItem);

            return(new NetworkReadResponse <T>(results, results.Count, false));
        }
예제 #5
0
        /// <summary>
        /// Perfoms finding in backend.
        /// </summary>
        /// <returns>The async task with the request results.</returns>
        protected async Task <NetworkReadResponse <T> > PerformNetworkFind()
        {
            try
            {
                string mongoQuery = this.BuildMongoQuery();

                bool isQueryModifierPresent = !string.IsNullOrEmpty(mongoQuery) ?
                                              mongoQuery.Contains(Constants.STR_QUERY_MODIFIER_SKIP) ||
                                              mongoQuery.Contains(Constants.STR_QUERY_MODIFIER_LIMIT) :
                                              false;

                if (DeltaSetFetchingEnabled && !isQueryModifierPresent)
                {
                    QueryCacheItem queryCacheItem = Client.CacheManager.GetQueryCacheItem(Collection, mongoQuery, null);

                    if (!Cache.IsCacheEmpty())
                    {
                        if (queryCacheItem != null && !string.IsNullOrEmpty(queryCacheItem.lastRequest))
                        {
                            // Able to perform server-side delta set fetch
                            NetworkRequest <DeltaSetResponse <T> > request = Client.NetworkFactory.BuildDeltaSetRequest <DeltaSetResponse <T> >(queryCacheItem.collectionName, queryCacheItem.lastRequest, queryCacheItem.query);
                            DeltaSetResponse <T> results = null;
                            try
                            {
                                results = await request.ExecuteAsync().ConfigureAwait(false);
                            }
                            catch (KinveyException ke)
                            {
                                // Regardless of the error, remove the QueryCacheItem if it exists
                                Client.CacheManager.DeleteQueryCacheItem(queryCacheItem);

                                switch (ke.StatusCode)
                                {
                                case 400:     // ResultSetSizeExceeded or ParameterValueOutOfRange
                                    if (ke.Error.Equals(Constants.STR_ERROR_BACKEND_RESULT_SET_SIZE_EXCEEDED))
                                    {
                                        // This means that there are greater than 10k items in the delta set.
                                        // Clear QueryCache table, perform a regular GET
                                        // and capture x-kinvey-request-start time
                                        return(await PerformNetworkInitialDeltaGet(mongoQuery).ConfigureAwait(false));
                                    }
                                    else if (ke.Error.Equals(Constants.STR_ERROR_BACKEND_PARAMETER_VALUE_OUT_OF_RANGE))
                                    {
                                        // This means that the last sync time for delta set is too far back, or
                                        // the backend was enabled for delta set after the client was enabled
                                        // and already attempted a GET.

                                        // Perform regular GET and capture x-kinvey-request-start time
                                        return(await PerformNetworkInitialDeltaGet(mongoQuery).ConfigureAwait(false));
                                    }
                                    break;

                                case 403:     // MissingConfiguration
                                    if (ke.Error.Equals(Constants.STR_ERROR_BACKEND_MISSING_CONFIGURATION))
                                    {
                                        // This means that server-side delta sync
                                        // is not enabled - should perform a regular
                                        // GET and capture x-kinvey-request-start time
                                        return(await PerformNetworkInitialDeltaGet(mongoQuery).ConfigureAwait(false));
                                    }
                                    break;

                                default:
                                    // This is not a delta sync specific error
                                    throw;
                                }
                            }

                            // With the _deltaset endpoint result from the server:

                            // 1 - Apply deleted set to local cache
                            List <string> listDeletedIDs = new List <string>();
                            foreach (var deletedItem in results.Deleted)
                            {
                                listDeletedIDs.Add(deletedItem.ID);
                            }
                            Cache.DeleteByIDs(listDeletedIDs);

                            // 2 - Apply changed set to local cache
                            Cache.RefreshCache(results.Changed);

                            // 3 - Update the last request time for this combination
                            // of collection:query
                            queryCacheItem.lastRequest = request.RequestStartTime;
                            Client.CacheManager.SetQueryCacheItem(queryCacheItem);

                            // 4 - Return network results
                            return(new NetworkReadResponse <T>(results.Changed, results.Changed.Count, true));
                        }
                        else
                        {
                            // Perform regular GET and capture x-kinvey-request-start time
                            return(await PerformNetworkInitialDeltaGet(mongoQuery).ConfigureAwait(false));
                        }
                    }
                    else
                    {
                        // Perform regular GET and capture x-kinvey-request-start time
                        return(await PerformNetworkInitialDeltaGet(mongoQuery, queryCacheItem).ConfigureAwait(false));
                    }
                }

                return(await PerformNetworkGet(mongoQuery).ConfigureAwait(false));
            }
            catch (KinveyException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new KinveyException(EnumErrorCategory.ERROR_DATASTORE_NETWORK,
                                          EnumErrorCode.ERROR_GENERAL,
                                          "Error in FindAsync() for network results.",
                                          e);
            }
        }