github.com/dschalla/mattermost-server@v4.8.1-rc1+incompatible/store/sqlstore/upgrade.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "os" 8 "strings" 9 "time" 10 11 l4g "github.com/alecthomas/log4go" 12 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/utils" 15 ) 16 17 const ( 18 VERSION_4_8_1 = "4.8.1" 19 VERSION_4_8_0 = "4.8.0" 20 VERSION_4_7_2 = "4.7.2" 21 VERSION_4_7_1 = "4.7.1" 22 VERSION_4_7_0 = "4.7.0" 23 VERSION_4_6_0 = "4.6.0" 24 VERSION_4_5_0 = "4.5.0" 25 VERSION_4_4_0 = "4.4.0" 26 VERSION_4_3_0 = "4.3.0" 27 VERSION_4_2_0 = "4.2.0" 28 VERSION_4_1_0 = "4.1.0" 29 VERSION_4_0_0 = "4.0.0" 30 VERSION_3_10_0 = "3.10.0" 31 VERSION_3_9_0 = "3.9.0" 32 VERSION_3_8_0 = "3.8.0" 33 VERSION_3_7_0 = "3.7.0" 34 VERSION_3_6_0 = "3.6.0" 35 VERSION_3_5_0 = "3.5.0" 36 VERSION_3_4_0 = "3.4.0" 37 VERSION_3_3_0 = "3.3.0" 38 VERSION_3_2_0 = "3.2.0" 39 VERSION_3_1_0 = "3.1.0" 40 VERSION_3_0_0 = "3.0.0" 41 OLDEST_SUPPORTED_VERSION = VERSION_3_0_0 42 ) 43 44 const ( 45 EXIT_VERSION_SAVE_MISSING = 1001 46 EXIT_TOO_OLD = 1002 47 EXIT_VERSION_SAVE = 1003 48 EXIT_THEME_MIGRATION = 1004 49 ) 50 51 func UpgradeDatabase(sqlStore SqlStore) { 52 53 UpgradeDatabaseToVersion31(sqlStore) 54 UpgradeDatabaseToVersion32(sqlStore) 55 UpgradeDatabaseToVersion33(sqlStore) 56 UpgradeDatabaseToVersion34(sqlStore) 57 UpgradeDatabaseToVersion35(sqlStore) 58 UpgradeDatabaseToVersion36(sqlStore) 59 UpgradeDatabaseToVersion37(sqlStore) 60 UpgradeDatabaseToVersion38(sqlStore) 61 UpgradeDatabaseToVersion39(sqlStore) 62 UpgradeDatabaseToVersion310(sqlStore) 63 UpgradeDatabaseToVersion40(sqlStore) 64 UpgradeDatabaseToVersion41(sqlStore) 65 UpgradeDatabaseToVersion42(sqlStore) 66 UpgradeDatabaseToVersion43(sqlStore) 67 UpgradeDatabaseToVersion44(sqlStore) 68 UpgradeDatabaseToVersion45(sqlStore) 69 UpgradeDatabaseToVersion46(sqlStore) 70 UpgradeDatabaseToVersion47(sqlStore) 71 UpgradeDatabaseToVersion471(sqlStore) 72 UpgradeDatabaseToVersion472(sqlStore) 73 UpgradeDatabaseToVersion48(sqlStore) 74 UpgradeDatabaseToVersion481(sqlStore) 75 76 // If the SchemaVersion is empty this this is the first time it has ran 77 // so lets set it to the current version. 78 if sqlStore.GetCurrentSchemaVersion() == "" { 79 if result := <-sqlStore.System().SaveOrUpdate(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil { 80 l4g.Critical(result.Err.Error()) 81 time.Sleep(time.Second) 82 os.Exit(EXIT_VERSION_SAVE_MISSING) 83 } 84 85 l4g.Info(utils.T("store.sql.schema_set.info"), model.CurrentVersion) 86 } 87 88 // If we're not on the current version then it's too old to be upgraded 89 if sqlStore.GetCurrentSchemaVersion() != model.CurrentVersion { 90 l4g.Critical(utils.T("store.sql.schema_version.critical"), sqlStore.GetCurrentSchemaVersion(), OLDEST_SUPPORTED_VERSION, model.CurrentVersion, OLDEST_SUPPORTED_VERSION) 91 time.Sleep(time.Second) 92 os.Exit(EXIT_TOO_OLD) 93 } 94 } 95 96 func saveSchemaVersion(sqlStore SqlStore, version string) { 97 if result := <-sqlStore.System().Update(&model.System{Name: "Version", Value: version}); result.Err != nil { 98 l4g.Critical(result.Err.Error()) 99 time.Sleep(time.Second) 100 os.Exit(EXIT_VERSION_SAVE) 101 } 102 103 l4g.Warn(utils.T("store.sql.upgraded.warn"), version) 104 } 105 106 func shouldPerformUpgrade(sqlStore SqlStore, currentSchemaVersion string, expectedSchemaVersion string) bool { 107 if sqlStore.GetCurrentSchemaVersion() == currentSchemaVersion { 108 l4g.Warn(utils.T("store.sql.schema_out_of_date.warn"), currentSchemaVersion) 109 l4g.Warn(utils.T("store.sql.schema_upgrade_attempt.warn"), expectedSchemaVersion) 110 111 return true 112 } 113 114 return false 115 } 116 117 func UpgradeDatabaseToVersion31(sqlStore SqlStore) { 118 if shouldPerformUpgrade(sqlStore, VERSION_3_0_0, VERSION_3_1_0) { 119 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "") 120 saveSchemaVersion(sqlStore, VERSION_3_1_0) 121 } 122 } 123 124 func UpgradeDatabaseToVersion32(sqlStore SqlStore) { 125 if shouldPerformUpgrade(sqlStore, VERSION_3_1_0, VERSION_3_2_0) { 126 sqlStore.CreateColumnIfNotExists("TeamMembers", "DeleteAt", "bigint(20)", "bigint", "0") 127 128 saveSchemaVersion(sqlStore, VERSION_3_2_0) 129 } 130 } 131 132 func themeMigrationFailed(err error) { 133 l4g.Critical(utils.T("store.sql_user.migrate_theme.critical"), err) 134 time.Sleep(time.Second) 135 os.Exit(EXIT_THEME_MIGRATION) 136 } 137 138 func UpgradeDatabaseToVersion33(sqlStore SqlStore) { 139 if shouldPerformUpgrade(sqlStore, VERSION_3_2_0, VERSION_3_3_0) { 140 if sqlStore.DoesColumnExist("Users", "ThemeProps") { 141 params := map[string]interface{}{ 142 "Category": model.PREFERENCE_CATEGORY_THEME, 143 "Name": "", 144 } 145 146 transaction, err := sqlStore.GetMaster().Begin() 147 if err != nil { 148 themeMigrationFailed(err) 149 } 150 151 // increase size of Value column of Preferences table to match the size of the ThemeProps column 152 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 153 if _, err := transaction.Exec("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil { 154 themeMigrationFailed(err) 155 } 156 } else if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL { 157 if _, err := transaction.Exec("ALTER TABLE Preferences MODIFY Value text"); err != nil { 158 themeMigrationFailed(err) 159 } 160 } 161 162 // copy data across 163 if _, err := transaction.Exec( 164 `INSERT INTO 165 Preferences(UserId, Category, Name, Value) 166 SELECT 167 Id, '`+model.PREFERENCE_CATEGORY_THEME+`', '', ThemeProps 168 FROM 169 Users 170 WHERE 171 Users.ThemeProps != 'null'`, params); err != nil { 172 themeMigrationFailed(err) 173 } 174 175 // delete old data 176 if _, err := transaction.Exec("ALTER TABLE Users DROP COLUMN ThemeProps"); err != nil { 177 themeMigrationFailed(err) 178 } 179 180 if err := transaction.Commit(); err != nil { 181 themeMigrationFailed(err) 182 } 183 184 // rename solarized_* code themes to solarized-* to match client changes in 3.0 185 var data model.Preferences 186 if _, err := sqlStore.GetMaster().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PREFERENCE_CATEGORY_THEME+"' AND Value LIKE '%solarized_%'"); err == nil { 187 for i := range data { 188 data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1) 189 } 190 191 sqlStore.Preference().Save(&data) 192 } 193 } 194 195 sqlStore.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0") 196 sqlStore.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "") 197 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "") 198 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "") 199 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0") 200 201 if sqlStore.DoesColumnExist("OAuthAccessData", "AuthCode") { 202 sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData") 203 sqlStore.RemoveColumnIfExists("OAuthAccessData", "AuthCode") 204 } 205 206 sqlStore.RemoveColumnIfExists("Users", "LastActivityAt") 207 sqlStore.RemoveColumnIfExists("Users", "LastPingAt") 208 209 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0") 210 211 saveSchemaVersion(sqlStore, VERSION_3_3_0) 212 } 213 } 214 215 func UpgradeDatabaseToVersion34(sqlStore SqlStore) { 216 if shouldPerformUpgrade(sqlStore, VERSION_3_3_0, VERSION_3_4_0) { 217 sqlStore.CreateColumnIfNotExists("Status", "Manual", "BOOLEAN", "BOOLEAN", "0") 218 sqlStore.CreateColumnIfNotExists("Status", "ActiveChannel", "varchar(26)", "varchar(26)", "") 219 220 saveSchemaVersion(sqlStore, VERSION_3_4_0) 221 } 222 } 223 224 func UpgradeDatabaseToVersion35(sqlStore SqlStore) { 225 if shouldPerformUpgrade(sqlStore, VERSION_3_4_0, VERSION_3_5_0) { 226 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user' WHERE Roles = ''") 227 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user system_admin' WHERE Roles = 'system_admin'") 228 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user' WHERE Roles = ''") 229 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user team_admin' WHERE Roles = 'admin'") 230 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user' WHERE Roles = ''") 231 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user channel_admin' WHERE Roles = 'admin'") 232 233 // The rest of the migration from Filenames -> FileIds is done lazily in api.GetFileInfosForPost 234 sqlStore.CreateColumnIfNotExists("Posts", "FileIds", "varchar(150)", "varchar(150)", "[]") 235 236 // Increase maximum length of the Channel table Purpose column. 237 if sqlStore.GetMaxLengthOfColumnIfExists("Channels", "Purpose") != "250" { 238 sqlStore.AlterColumnTypeIfExists("Channels", "Purpose", "varchar(250)", "varchar(250)") 239 } 240 241 sqlStore.Session().RemoveAllSessions() 242 243 saveSchemaVersion(sqlStore, VERSION_3_5_0) 244 } 245 } 246 247 func UpgradeDatabaseToVersion36(sqlStore SqlStore) { 248 if shouldPerformUpgrade(sqlStore, VERSION_3_5_0, VERSION_3_6_0) { 249 sqlStore.CreateColumnIfNotExists("Posts", "HasReactions", "tinyint", "boolean", "0") 250 251 // Create Team Description column 252 sqlStore.CreateColumnIfNotExists("Teams", "Description", "varchar(255)", "varchar(255)", "") 253 254 // Add a Position column to users. 255 sqlStore.CreateColumnIfNotExists("Users", "Position", "varchar(64)", "varchar(64)", "") 256 257 // Remove ActiveChannel column from Status 258 sqlStore.RemoveColumnIfExists("Status", "ActiveChannel") 259 260 saveSchemaVersion(sqlStore, VERSION_3_6_0) 261 } 262 } 263 264 func UpgradeDatabaseToVersion37(sqlStore SqlStore) { 265 if shouldPerformUpgrade(sqlStore, VERSION_3_6_0, VERSION_3_7_0) { 266 // Add EditAt column to Posts 267 sqlStore.CreateColumnIfNotExists("Posts", "EditAt", " bigint", " bigint", "0") 268 269 saveSchemaVersion(sqlStore, VERSION_3_7_0) 270 } 271 } 272 273 func UpgradeDatabaseToVersion38(sqlStore SqlStore) { 274 if shouldPerformUpgrade(sqlStore, VERSION_3_7_0, VERSION_3_8_0) { 275 // Add the IsPinned column to posts. 276 sqlStore.CreateColumnIfNotExists("Posts", "IsPinned", "boolean", "boolean", "0") 277 278 saveSchemaVersion(sqlStore, VERSION_3_8_0) 279 } 280 } 281 282 func UpgradeDatabaseToVersion39(sqlStore SqlStore) { 283 if shouldPerformUpgrade(sqlStore, VERSION_3_8_0, VERSION_3_9_0) { 284 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "Scope", "varchar(128)", "varchar(128)", model.DEFAULT_SCOPE) 285 sqlStore.RemoveTableIfExists("PasswordRecovery") 286 287 saveSchemaVersion(sqlStore, VERSION_3_9_0) 288 } 289 } 290 291 func UpgradeDatabaseToVersion310(sqlStore SqlStore) { 292 if shouldPerformUpgrade(sqlStore, VERSION_3_9_0, VERSION_3_10_0) { 293 saveSchemaVersion(sqlStore, VERSION_3_10_0) 294 } 295 } 296 297 func UpgradeDatabaseToVersion40(sqlStore SqlStore) { 298 if shouldPerformUpgrade(sqlStore, VERSION_3_10_0, VERSION_4_0_0) { 299 saveSchemaVersion(sqlStore, VERSION_4_0_0) 300 } 301 } 302 303 func UpgradeDatabaseToVersion41(sqlStore SqlStore) { 304 if shouldPerformUpgrade(sqlStore, VERSION_4_0_0, VERSION_4_1_0) { 305 // Increase maximum length of the Users table Roles column. 306 if sqlStore.GetMaxLengthOfColumnIfExists("Users", "Roles") != "256" { 307 sqlStore.AlterColumnTypeIfExists("Users", "Roles", "varchar(256)", "varchar(256)") 308 } 309 310 sqlStore.RemoveTableIfExists("JobStatuses") 311 312 saveSchemaVersion(sqlStore, VERSION_4_1_0) 313 } 314 } 315 316 func UpgradeDatabaseToVersion42(sqlStore SqlStore) { 317 if shouldPerformUpgrade(sqlStore, VERSION_4_1_0, VERSION_4_2_0) { 318 saveSchemaVersion(sqlStore, VERSION_4_2_0) 319 } 320 } 321 322 func UpgradeDatabaseToVersion43(sqlStore SqlStore) { 323 if shouldPerformUpgrade(sqlStore, VERSION_4_2_0, VERSION_4_3_0) { 324 saveSchemaVersion(sqlStore, VERSION_4_3_0) 325 } 326 } 327 328 func UpgradeDatabaseToVersion44(sqlStore SqlStore) { 329 if shouldPerformUpgrade(sqlStore, VERSION_4_3_0, VERSION_4_4_0) { 330 // Add the IsActive column to UserAccessToken. 331 sqlStore.CreateColumnIfNotExists("UserAccessTokens", "IsActive", "boolean", "boolean", "1") 332 333 saveSchemaVersion(sqlStore, VERSION_4_4_0) 334 } 335 } 336 337 func UpgradeDatabaseToVersion45(sqlStore SqlStore) { 338 if shouldPerformUpgrade(sqlStore, VERSION_4_4_0, VERSION_4_5_0) { 339 saveSchemaVersion(sqlStore, VERSION_4_5_0) 340 } 341 } 342 343 func UpgradeDatabaseToVersion46(sqlStore SqlStore) { 344 if shouldPerformUpgrade(sqlStore, VERSION_4_5_0, VERSION_4_6_0) { 345 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "Username", "varchar(64)", "varchar(64)", "") 346 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "") 347 saveSchemaVersion(sqlStore, VERSION_4_6_0) 348 } 349 } 350 351 func UpgradeDatabaseToVersion47(sqlStore SqlStore) { 352 if shouldPerformUpgrade(sqlStore, VERSION_4_6_0, VERSION_4_7_0) { 353 sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)") 354 sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)") 355 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 356 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username") 357 saveSchemaVersion(sqlStore, VERSION_4_7_0) 358 } 359 } 360 361 // If any new instances started with 4.7, they would have the bad Email column on the 362 // ChannelMemberHistory table. So for those cases we need to do an upgrade between 363 // 4.7.0 and 4.7.1 364 func UpgradeDatabaseToVersion471(sqlStore SqlStore) { 365 if shouldPerformUpgrade(sqlStore, VERSION_4_7_0, VERSION_4_7_1) { 366 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 367 saveSchemaVersion(sqlStore, VERSION_4_7_1) 368 } 369 } 370 371 func UpgradeDatabaseToVersion472(sqlStore SqlStore) { 372 if shouldPerformUpgrade(sqlStore, VERSION_4_7_1, VERSION_4_7_2) { 373 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 374 saveSchemaVersion(sqlStore, VERSION_4_7_2) 375 } 376 } 377 378 func UpgradeDatabaseToVersion48(sqlStore SqlStore) { 379 if shouldPerformUpgrade(sqlStore, VERSION_4_7_2, VERSION_4_8_0) { 380 saveSchemaVersion(sqlStore, VERSION_4_8_0) 381 } 382 } 383 384 func UpgradeDatabaseToVersion481(sqlStore SqlStore) { 385 if shouldPerformUpgrade(sqlStore, VERSION_4_8_0, VERSION_4_8_1) { 386 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 387 saveSchemaVersion(sqlStore, VERSION_4_8_1) 388 } 389 }