#pragma warning restore 649 #endregion private void RebuildDatabase(int coreDbVersion) { if (coreDbVersion != 0) { var args = new SQLiteDataContextUpgradeEventArgs("Core", "Warning: Your database is from a beta build, so some settings will be lost during the upgrade.", coreDbVersion, CurrentCoreDbVersion); OnBeforeUpgrade(args); if (args.CancelUpgrade) { throw new DatabaseUpgradeCanceledException("Core"); } } var startTime = DateTime.Now; Debug.WriteLine("BEGIN REBUILD CORE DATABASE"); // Delete and recreate all the core tables CreateTables(); InitDatabase(); RebuildTables(RebuildableTable.All); // Set the ShowInYamster flag for any groups that were synced Mapper.ExecuteNonQuery(@" UPDATE GroupStates SET ShowInYamster = 1 WHERE GroupId IN ( SELECT GroupId FROM Messages GROUP BY GroupId ) "); var totalTime = DateTime.Now - startTime; Debug.WriteLine("END REBUILD CORE DATABASE: {0} secs processing time", totalTime.TotalSeconds); if (coreDbVersion != 0) { OnAfterUpgrade(); } return; }
void UpgradeDatabase() { // Validate the database state int coreDbVersion = archiveDb.GetObjectVersion("Core"); bool inactiveArchiveDb = this.archiveDb.IsInactive(); if (coreDbVersion == CurrentCoreDbVersion) { return; } if (coreDbVersion > CurrentCoreDbVersion) { throw new UnsupportedDatabaseVersionException("Core", coreDbVersion, CurrentCoreDbVersion); } if (inactiveArchiveDb) { if (coreDbVersion < MinimumUpgradeableCoreDbVersionWithoutArchiveDb) { // The database cannot be upgraded because the ArchiveDB is missing, // e.g. because the data was imported using CsvDumpLoader throw new UnsupportedDatabaseVersionException("Core", coreDbVersion, CurrentCoreDbVersion); } } if (coreDbVersion < MinimumUpgradeableCoreDbVersion) { RebuildDatabase(coreDbVersion); return; } var args2 = new SQLiteDataContextUpgradeEventArgs("Core", "For a large database, the upgrade may take a while. Please be patient.", coreDbVersion, CurrentCoreDbVersion); OnBeforeUpgrade(args2); if (args2.CancelUpgrade) { throw new DatabaseUpgradeCanceledException("Core"); } var startTime = DateTime.Now; Debug.WriteLine("BEGIN UPGRADE CORE DATABASE"); RebuildableTable alreadyRebuiltTables = RebuildableTable.None; // Upgrade 1004 -> 1005 if (coreDbVersion < 1005) { Debug.Assert(coreDbVersion == 1004); using (var transaction = this.BeginTransaction()) { string sqlTemplate = @" ALTER TABLE [{0}] ADD COLUMN [ChangeNumber] INTEGER NOT NULL DEFAULT -1; -- Ensure ChangeNumber is unique UPDATE [{0}] SET [ChangeNumber] = [RowId]; CREATE UNIQUE INDEX [{0}_Index0] ON [{0}] ([ChangeNumber]); CREATE TRIGGER [{0}_ChangeNumberTrigger0] AFTER INSERT ON [{0}] BEGIN UPDATE [{0}] SET [ChangeNumber] = (SELECT MAX([ChangeNumber]) FROM [{0}] LIMIT 1)+1 WHERE ROWID = NEW.ROWID; END; CREATE TRIGGER [{0}_ChangeNumberTrigger1] AFTER UPDATE ON [{0}] BEGIN UPDATE [{0}] SET [ChangeNumber] = (SELECT MAX([ChangeNumber]) FROM [{0}] LIMIT 1)+1 WHERE ROWID = NEW.ROWID; END; "; foreach (string tableName in new string[] { "GroupStates", "MessageStates" }) { string sql = string.Format(sqlTemplate, tableName); this.Mapper.ExecuteNonQuery(sql); } this.RebuildTablesIfNeeded( RebuildableTable.Groups | RebuildableTable.Messages | RebuildableTable.Users, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1005); transaction.Commit(); coreDbVersion = 1005; } } // Upgrade 1005 -> 1006 if (coreDbVersion < 1006) { Debug.Assert(coreDbVersion == 1005); using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added CurrentUserId column RebuildableTable.Properties, ref alreadyRebuiltTables ); // Group name changed in this version InitVirtualGroups(); archiveDb.SetObjectVersion("Core", 1006); transaction.Commit(); coreDbVersion = 1006; } } // Upgrade 1006 -> 1007 if (coreDbVersion < 1007) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added Conversations table RebuildableTable.Conversations // Added ConversationId column | RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1007); transaction.Commit(); coreDbVersion = 1007; } } // Upgrade 1007 -> 1008 if (coreDbVersion < 1008) { using (var transaction = this.BeginTransaction()) { // Added "(All Company)" group InitVirtualGroups(); GroupStates.InsertRecord(new DbGroupState() { GroupId = YamsterGroup.AllCompanyGroupId, ShowInYamster = true, ShouldSync = false, TrackRead = true }); archiveDb.SetObjectVersion("Core", 1008); transaction.Commit(); coreDbVersion = 1008; } } // Upgrade 1008 -> 1009 if (coreDbVersion < 1009) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Replaced DbConversation.ParticipantsJson with ParticipantUserIds RebuildableTable.Conversations // Added LikingUserIds and NotifiedUserIds | RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1009); transaction.Commit(); coreDbVersion = 1009; } } // Upgrade 1009 -> 1010 if (coreDbVersion < 1010) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added CurrentNetworkId, FollowYamsterLastAskedUtc, and FollowYamsterState RebuildableTable.Properties, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1010); transaction.Commit(); coreDbVersion = 1010; } } // Upgrade 1010 -> 1011 if (coreDbVersion < 1011) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Fixed issue where liking users weren't being extracted from the Messages // table into the Users table RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1011); transaction.Commit(); coreDbVersion = 1011; } } // Upgrade 1011 -> 1012 if (coreDbVersion < 1012) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added SyncInbox RebuildableTable.Properties // These tables are new | RebuildableTable.SyncingFeeds | RebuildableTable.SyncingThreads, ref alreadyRebuiltTables ); // This could have been lost if the ArchiveDb was regenerated if (this.Mapper.QueryScalar <long>( "SELECT COUNT(*) FROM sqlite_master WHERE name ='ArchiveSyncState' and type='table'") > 0) { var syncStates = this.Mapper.Query <V1011_DbArchiveSyncState>( "SELECT [GroupId], [Json] FROM [ArchiveSyncState]"); foreach (var syncState in syncStates) { var jsonGroupState = SQLiteJsonConverter.LoadFromJson <V1011_MessagePullerGroupState>(syncState.Json); // Build a DbSyncingFeed record var syncingFeed = new JsonSyncingFeed() { ReachedEmptyResult = jsonGroupState.ReachedEmptyResult, SpanCyclesSinceCheckNew = jsonGroupState.SpanCyclesSinceCheckNew, LastUpdateUtc = jsonGroupState.LastUpdateUtc, LastCheckNewUtc = jsonGroupState.LastCheckNewUtc }; foreach (var span in jsonGroupState.Spans) { syncingFeed.AddSpan(new JsonMessagePullerSpan() { StartTimeUtc = span.StartTimeUtc, StartMessageId = span.StartMessageId, EndMessageId = span.EndMessageId } ); } this.UpdateJsonSyncingFeed(syncState.GroupId, syncingFeed); // Build DbSyncingThread records foreach (var gappedThread in jsonGroupState.GappedThreads) { var syncingThread = new DbSyncingThread() { ThreadId = gappedThread.ThreadId, FeedId = syncState.GroupId, LastPulledMessageId = gappedThread.LastPulledMessageId, StopMessageId = gappedThread.StopMessageId, RetryCount = gappedThread.RetryCount }; this.SyncingThreads.InsertRecord(syncingThread); } } this.Mapper.ExecuteNonQuery("DROP TABLE [ArchiveSyncState]"); } archiveDb.SetObjectVersion("Core", 1012); transaction.Commit(); coreDbVersion = 1012; } } // Upgrade 1012 -> 1013 if (coreDbVersion < 1013) { using (var transaction = this.BeginTransaction()) { this.Mapper.CreateTable(this.ThreadStates); // Make sure we have DbThreadState records for each thread foreach (var result in this.Mapper.Query <DbInt64Result>( "SELECT DISTINCT [ThreadId] AS [Value] FROM [Messages]")) { this.ThreadStates.InsertRecord(new DbThreadState() { ThreadId = result.Value }, SQLiteConflictResolution.Ignore); } archiveDb.SetObjectVersion("Core", 1013); transaction.Commit(); coreDbVersion = 1013; } } // Upgrade 1013 -> 1014 if (coreDbVersion < 1014) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added DbMessage.MessageIdRepliedTo RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1014); transaction.Commit(); coreDbVersion = 1014; } } // Upgrade 1014 -> 1015 if (coreDbVersion < 1015) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added DbMessage.AttachmentWidth/AttachmentHeight RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1015); transaction.Commit(); coreDbVersion = 1015; } } // Upgrade 1015 -> 1016 if (coreDbVersion < 1016) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added DbUser.Alias RebuildableTable.Users, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1016); transaction.Commit(); coreDbVersion = 1016; } } // Upgrade 1016 -> 1017 if (coreDbVersion < 1017) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Removed FollowYamsterLastAskedUtc and FollowYamsterState RebuildableTable.Properties, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1017); transaction.Commit(); coreDbVersion = 1017; } } // Upgrade 1017 -> 1018 if (coreDbVersion < 1018) { using (var transaction = this.BeginTransaction()) { this.Mapper.ExecuteNonQuery(@"ALTER TABLE [MessageStates] ADD COLUMN [Deleted] INTEGER NOT NULL DEFAULT 0"); this.RebuildTablesIfNeeded( // Added DbMessage.MessageType RebuildableTable.Messages, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1018); transaction.Commit(); coreDbVersion = 1018; } } // Upgrade 1018 -> 1019 if (coreDbVersion < 1019) { using (var transaction = this.BeginTransaction()) { this.RebuildTablesIfNeeded( // Added DbUser.Alias RebuildableTable.Users, ref alreadyRebuiltTables ); archiveDb.SetObjectVersion("Core", 1019); transaction.Commit(); coreDbVersion = 1019; } } if (coreDbVersion != CurrentCoreDbVersion) { // This is a program bug throw new InvalidOperationException("Upgrade failed"); } var totalTime = DateTime.Now - startTime; Debug.WriteLine("END UPGRADE CORE DATABASE: {0} secs processing time", totalTime.TotalSeconds); OnAfterUpgrade(); }