public void TestTreeRemoval() { RunAsync(async delegate { var dirty = await DataStore.Table <TimeEntryData> ().ToListAsync(); var graph = await RelatedDataGraph.FromDirty(dirty); var projectRows = await DataStore.Table <ProjectData> ().Where(r => r.RemoteId == 1).ToListAsync(); var project = projectRows [0]; graph.Remove(project); }); }
private static async Task <bool> PushChanges() { var log = ServiceContainer.Resolve <Logger> (); var hasErrors = false; log.Info(Tag, "Pushing local changes to server."); // Construct dependency graph: var allDirtyData = await GetAllDirtyData().ConfigureAwait(false); var graph = await RelatedDataGraph.FromDirty(allDirtyData).ConfigureAwait(false); // Start pushing the dependencies from the end nodes up var tasks = new List <PushTask> (); while (true) { tasks.Clear(); var dirtyDataObjects = graph.EndNodes.ToList(); if (dirtyDataObjects.Count == 0) { break; } foreach (var dataObject in dirtyDataObjects) { if (dataObject.RemoteRejected) { if (dataObject.RemoteId == null) { // Creation has failed, so remove the whole branch. graph.RemoveBranch(dataObject); log.Info(Tag, "Skipping {0} and everything that depends on it.", dataObject.ToIdString()); } else { graph.Remove(dataObject); log.Info(Tag, "Skipping {0}.", dataObject.ToIdString()); } } else { tasks.Add(new PushTask() { Task = PushDataObject(dataObject), Data = dataObject, }); } } // Nothing was pushed this round if (tasks.Count < 1) { continue; } await Task.WhenAll(tasks.Select(p => p.Task)).ConfigureAwait(false); foreach (var pushTask in tasks) { var dataObject = pushTask.Data; var error = pushTask.Task.Result; if (error != null) { if (dataObject.RemoteId == null) { // When creation fails, remove branch as there are models that depend on this // one, so there is no point in continuing with the branch. graph.RemoveBranch(dataObject); } else { graph.Remove(dataObject); } hasErrors = true; } else { graph.Remove(dataObject); } } } return(hasErrors); }