private async Task <List <GroupAggregationResults> > PerformNetworkAggregateFind() { List <GroupAggregationResults> networkResults = new List <GroupAggregationResults>(); try { string mongoQuery = this.BuildMongoQuery(); NetworkRequest <JArray> request = Client.NetworkFactory.BuildGetAggregateRequest <JArray>(Collection, reduceFunction, mongoQuery, groupField, aggregateField); JArray results = await request.ExecuteAsync(); if (results != null) { foreach (JToken obj in results) { GroupAggregationResults gar = new GroupAggregationResults(); gar.GroupField = (obj as JObject).GetValue(groupField)?.ToString(); gar.Result = (obj as JObject).GetValue("result").ToObject <int>(); networkResults.Add(gar); } } } catch (KinveyException) { throw; } catch (Exception e) { throw new KinveyException(EnumErrorCategory.ERROR_DATASTORE_NETWORK, EnumErrorCode.ERROR_GENERAL, "Error in FindAggregateAsync() for network results.", e); } return(networkResults); }
private async Task <Tuple <T, KinveyException, int> > HandlePushDELETE(PendingWriteAction pwa) { var offset = 0; KinveyException kinveyException = null; try { int result = 0; NetworkRequest <KinveyDeleteResponse> request = Client.NetworkFactory.buildDeleteRequest <KinveyDeleteResponse>(pwa.collection, pwa.entityId); KinveyDeleteResponse kdr = await request.ExecuteAsync().ConfigureAwait(false); if (kdr.count == 1) { result = SyncQueue.Remove(pwa); if (result == 0) { offset++; } } } catch (KinveyException ke) { kinveyException = ke; offset++; } return(new Tuple <T, KinveyException, int>(default(T), kinveyException, offset)); }
private async Task <Tuple <T, KinveyException, int> > HandlePushPUT(PendingWriteAction pwa) { T entity = default(T); var offset = 0; KinveyException kinveyException = null; try { int result = 0; var localEntity = Cache.FindByID(pwa.entityId); NetworkRequest <T> request = Client.NetworkFactory.buildUpdateRequest <T>(pwa.collection, localEntity, pwa.entityId); entity = await request.ExecuteAsync().ConfigureAwait(false); Cache.UpdateCacheSave(entity, pwa.entityId); result = SyncQueue.Remove(pwa); if (result == 0) { offset++; } } catch (KinveyException ke) { kinveyException = ke; offset++; } return(new Tuple <T, KinveyException, int>(entity, kinveyException, offset)); }
private async Task <uint> PerformNetworkCount() { uint networkCount = default(uint); try { string mongoQuery = this.BuildMongoQuery(); NetworkRequest <JObject> request = Client.NetworkFactory.buildGetCountRequest <JObject>(Collection, mongoQuery); JObject networkResults = await request.ExecuteAsync().ConfigureAwait(false); if (networkResults != null) { JToken count = networkResults.GetValue("count"); if (count != null) { networkCount = count.ToObject <uint>(); } else { throw new KinveyException(EnumErrorCategory.ERROR_DATASTORE_NETWORK, EnumErrorCode.ERROR_GENERAL, "Error in FindCountAsync() for network results."); } } } catch (KinveyException) { throw; } catch (Exception e) { throw new KinveyException(EnumErrorCategory.ERROR_DATASTORE_NETWORK, EnumErrorCode.ERROR_GENERAL, "Error in FindCountAsync() for network results.", e); } return(networkCount); }
private async Task <Tuple <T, KinveyException, int> > HandlePushPOST(PendingWriteAction pwa) { T entity = default(T); var offset = 0; KinveyException kinveyException = null; try { int result = 0; string tempID = pwa.entityId; var localEntity = Cache.FindByID(pwa.entityId); JObject obj = JObject.FromObject(localEntity); obj["_id"] = null; localEntity = Newtonsoft.Json.JsonConvert.DeserializeObject <T>(obj.ToString()); NetworkRequest <T> request = Client.NetworkFactory.buildCreateRequest <T>(pwa.collection, localEntity); entity = await request.ExecuteAsync().ConfigureAwait(false); Cache.UpdateCacheSave(entity, tempID); result = SyncQueue.Remove(pwa); if (result == 0) { offset++; } } catch (KinveyException ke) { kinveyException = ke; offset++; } return(new Tuple <T, KinveyException, int>(entity, kinveyException, offset)); }
public override async Task <T> ExecuteAsync() { T savedEntity = default(T); NetworkRequest <T> request = null; string entityID = null;; JToken idToken = JObject.FromObject(entity) ["_id"]; if (idToken != null && !String.IsNullOrEmpty(idToken.ToString())) { entityID = idToken.ToString(); request = Client.NetworkFactory.buildUpdateRequest(Collection, entity, entityID); } else { request = Client.NetworkFactory.buildCreateRequest(Collection, entity); } switch (Policy) { case WritePolicy.FORCE_LOCAL: // sync PendingWriteAction pendingAction = PendingWriteAction.buildFromRequest(request); string saveModeLocal = request.RequestMethod; string tempIdLocal = null; if (String.Equals("POST", saveModeLocal)) { tempIdLocal = PrepareCacheSave(ref entity); savedEntity = Cache.Save(entity); pendingAction.entityId = tempIdLocal; } else { savedEntity = Cache.Update(entity); } SyncQueue.Enqueue(pendingAction); break; case WritePolicy.FORCE_NETWORK: // network savedEntity = await request.ExecuteAsync(); break; case WritePolicy.NETWORK_THEN_LOCAL: // cache string saveModeNetworkThenLocal = request.RequestMethod; string tempIdNetworkThenLocal = null; if (String.Equals("POST", saveModeNetworkThenLocal)) { tempIdNetworkThenLocal = PrepareCacheSave(ref entity); Cache.Save(entity); } else { Cache.Update(entity); } // network save savedEntity = await request.ExecuteAsync(); if (tempIdNetworkThenLocal != null) { Cache.UpdateCacheSave(savedEntity, tempIdNetworkThenLocal); } break; case WritePolicy.LOCAL_THEN_NETWORK: string saveModeLocalThenNetwork = request.RequestMethod; // cache if (String.Equals("POST", saveModeLocalThenNetwork)) { entityID = PrepareCacheSave(ref entity); savedEntity = Cache.Save(entity); } else { savedEntity = Cache.Update(entity); } KinveyException kinveyException = null; Exception exception = null; try { // network save savedEntity = await request.ExecuteAsync(); } catch (KinveyException kinveyEx) { kinveyException = kinveyEx; } catch (Exception ex) { exception = ex; } if (kinveyException != null || exception != null) { // if the network request fails, save data to sync queue var localPendingAction = PendingWriteAction.buildFromRequest(request); localPendingAction.entityId = entityID; SyncQueue.Enqueue(localPendingAction); if (kinveyException != null) { throw kinveyException; } } else { Cache.UpdateCacheSave(savedEntity, entityID); } break; default: throw new KinveyException(EnumErrorCategory.ERROR_GENERAL, EnumErrorCode.ERROR_GENERAL, "Invalid write policy"); } return(savedEntity); }
/// <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); } }