private LastEntitySyncTime GetLastSyncTime <T>(SynchronizationParameters synchronizationParameters) where T : AbstractEntity, new() { string entityName = typeof(T).Name; LastEntitySyncTime lastSyncObj = DatabaseConnection.Connection.Query <LastEntitySyncTime>("select * from [LastEntitySyncTime] " + "where [EntityName] = ?", new[] { entityName }).FirstOrDefault(); if (lastSyncObj == null) { List <T> entities = DatabaseConnection.Connection.Query <T>("select * from [" + entityName + "]"); DateTime lastSyncTime = entities.Count == 0 ? default(DateTime) : entities.Select(o => o.ModifiedDate).Max(); DatabaseConnection.Connection.Insert(lastSyncObj = new LastEntitySyncTime { EntityName = entityName, LastDownloadTime = lastSyncTime }); } return(lastSyncObj); }
private async void DownloadAsync <T>(SynchronizationParameters synchronizationParameters, Action finishedNotification) where T : AbstractEntity, new() { LastEntitySyncTime lastSyncRecord = GetLastSyncTime <T>(synchronizationParameters); RestService <T> restService = new RestService <T>(synchronizationParameters); #if DEBUG Stopwatch watch = new Stopwatch(); TimeSpan elapsed; watch.Start(); #endif try { int pageCount = 0; DownloadResult <T> downloadResult; do { downloadResult = await restService.DownloadAsync(lastSyncRecord.LastDownloadTime, pageCount, GeneratedConstants.DownloadPageSize); #if DEBUG if (GeneratedConstants.LogDebug && typeof(T).Name == "GlucoseValue") { elapsed = watch.Elapsed; watch.Restart(); Debug.WriteLine("Download " + typeof(T).Name + " page=" + pageCount + ", size=" + GeneratedConstants.DownloadPageSize + " needed " + elapsed); } #endif pageCount++; if (previousTask != null) { await previousTask; } if (downloadResult.Items.Count > 0) { previousTask = Task.Factory.StartNew(() => { Stopwatch refreshWatch = new Stopwatch(); refreshWatch.Start(); List <T> objectsForUpdateLocal = new List <T>(downloadResult.Items); if (typeof(T) == typeof(DeletedRecord) && objectsForUpdateLocal.Count > 0) { foreach (T obj in objectsForUpdateLocal) { synchronizationParameters.RecordsToDelete++; DeletedRecord deletedRecord = obj as DeletedRecord; int deletedRecords = DatabaseConnection .Connection .Execute("delete from [" + deletedRecord.EntityName + "] where [Pk] = ?", new[] { deletedRecord.EntityPk }); if (synchronizationParameters.Refresh != null && refreshWatch.Elapsed >= TimeSpan.FromSeconds(1)) { synchronizationParameters.Refresh(); refreshWatch.Restart(); } synchronizationParameters.RecordsDeleted += deletedRecords; } DatabaseConnection.Connection.Execute("delete from DeletedRecord where EntityPk in (" + objectsForUpdateLocal.Select(o => "'" + (o as DeletedRecord).EntityPk + "'").Aggregate((i, j) => i + "," + j) + ")"); if (synchronizationParameters.Refresh != null && refreshWatch.Elapsed >= TimeSpan.FromSeconds(1)) { synchronizationParameters.Refresh(); refreshWatch.Restart(); } #if DEBUG if (GeneratedConstants.LogDebug) { elapsed = watch.Elapsed; watch.Restart(); Debug.WriteLine("Performing delete actions, count=" + objectsForUpdateLocal.Count + " needed " + elapsed); } #endif } else { foreach (T obj in objectsForUpdateLocal) { try { DatabaseConnection.Connection.Insert(obj); } catch (Exception) { DatabaseConnection.Connection.GetChildren(obj); obj.IsPending = false; DatabaseConnection.Connection.Update(obj); } synchronizationParameters.Downloaded++; if (synchronizationParameters.Refresh != null && refreshWatch.Elapsed >= TimeSpan.FromSeconds(1)) { synchronizationParameters.Refresh(); refreshWatch.Restart(); } } #if DEBUG if (GeneratedConstants.LogDebug && typeof(T).Name == "GlucoseValue") { elapsed = watch.Elapsed; watch.Restart(); Debug.WriteLine("Insert/update actions, count=" + objectsForUpdateLocal.Count + " needed " + elapsed); } #endif } if (!downloadResult.FetchNextPage) { lastSyncRecord.LastDownloadTime = objectsForUpdateLocal.Last().ModifiedDate; DatabaseConnection.Connection.Update(lastSyncRecord); } }); } } while (downloadResult.FetchNextPage); finishedNotification(); } catch (Exception exception) { Debug.WriteLine(exception.StackTrace); ExceptionHandler(synchronizationParameters, exception); } finally { synchronizationParameters.Refresh?.Invoke(); } }