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); } }
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); } }
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); } }
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)); }
/// <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); } }