public void InitializeDatabase() { if (!this.DatabaseExists()) { this.connection.CreateTable <Context>(); this.connection.CreateTable <Task>(); this.connection.CreateTable <Folder>(); this.connection.CreateTable <SystemView>(); this.connection.CreateTable <SmartView>(); this.connection.CreateTable <Tag>(); this.folders = new List <IFolder>(); this.contexts = new List <IContext>(); this.tasks = new List <ITask>(); this.views = new List <ISystemView>(); this.smartViews = new List <ISmartView>(); this.tags = new List <ITag>(); } else { try { this.folders = new List <IFolder>(this.connection.Table <Folder>()); } catch (FormatException) { DeviceFamily deviceFamily = DeviceFamily.Unkown; if (Ioc.HasType <IPlatformService>()) { deviceFamily = Ioc.Resolve <IPlatformService>().DeviceFamily; } var trackingManager = new TrackingManager(true, deviceFamily); DatebaseDateTimeFixer.Run(trackingManager, this.connection); this.folders = new List <IFolder>(this.connection.Table <Folder>()); trackingManager.Event(TrackingSource.Storage, "FormatException", "Fixed"); } this.contexts = new List <IContext>(this.connection.Table <Context>()); // check if the Task table contains the ParentId column if (!this.connection.GetTableInfo("Tasks").Any(c => c.Name == "ParentId")) { this.connection.MigrateTable <Task>(); } this.tasks = new List <ITask>(this.connection.Table <Task>()); // check duplicate sync id var syncIds = new HashSet <string>(); foreach (var task in this.tasks.Where(t => t.SyncId != null).ToList()) { if (!syncIds.Contains(task.SyncId)) { syncIds.Add(task.SyncId); } else { LogService.Log("Workbook", $"Removing duplicate task {task.Title}"); this.tasks.Remove(task); this.connection.Delete(task); } } this.views = new List <ISystemView>(); bool hasBeganDeleteTransaction = false; foreach (var view in this.connection.Table <SystemView>().ToList()) { // make sure we don't add twice the same view kind in the list // this should never happens, but... it already did for a single user ! if (this.views.FirstOrDefault(v => v.ViewKind == view.ViewKind) == null) { this.views.Add(view); } else { if (!hasBeganDeleteTransaction) { this.connection.BeginTransaction(); hasBeganDeleteTransaction = true; } this.connection.Delete(view); } } if (hasBeganDeleteTransaction) { this.connection.Commit(); } if (!this.connection.GetTableInfo("SmartViews").Any()) { this.connection.CreateTable <SmartView>(); } this.smartViews = new List <ISmartView>(); foreach (var view in this.connection.Table <SmartView>()) { this.smartViews.Add(view); } if (!this.connection.GetTableInfo("Tags").Any()) { // the Tag column doesn't exists yet this.connection.CreateTable <Tag>(); var tags = this.tasks .SelectMany(t => t.Tags != null ? t.Tags.Split(Constants.TagSeparator) : Enumerable.Empty <string>()) .Distinct() .Where(t => !string.IsNullOrWhiteSpace(t)) .OrderBy(t => t) .ToList(); foreach (var tag in tags) { this.AddTag(new Tag { Name = tag, TaskGroup = TaskGroup.DueDate, GroupAscending = true, }); } } this.tags = new List <ITag>(this.connection.Table <Tag>()); foreach (var task in this.tasks.OfType <Task>()) { if (task.ContextId >= 0) { task.Context = this.contexts.SingleOrDefault(c => c.Id == task.ContextId); } if (task.FolderId >= 0) { task.Folder = this.folders.SingleOrDefault(f => f.Id == task.FolderId); } } } foreach (var folder in this.folders) { this.objectTracker.EnsureIsTracked(folder); } foreach (var context in this.contexts) { this.objectTracker.EnsureIsTracked(context); } foreach (var task in this.tasks) { this.objectTracker.EnsureIsTracked(task); } foreach (var view in this.views) { this.objectTracker.EnsureIsTracked(view); } foreach (var smartview in this.smartViews) { this.objectTracker.EnsureIsTracked(smartview); } foreach (var tag in this.tags) { this.objectTracker.EnsureIsTracked(tag); } }