github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/sqlstore/upgrade.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "encoding/json" 8 "os" 9 "strings" 10 "time" 11 12 "github.com/blang/semver" 13 "github.com/pkg/errors" 14 15 "github.com/mattermost/mattermost-server/v5/mlog" 16 "github.com/mattermost/mattermost-server/v5/model" 17 "github.com/mattermost/mattermost-server/v5/services/timezones" 18 ) 19 20 const ( 21 CURRENT_SCHEMA_VERSION = VERSION_5_26_0 22 VERSION_5_27_0 = "5.27.0" 23 VERSION_5_26_0 = "5.26.0" 24 VERSION_5_25_0 = "5.25.0" 25 VERSION_5_24_0 = "5.24.0" 26 VERSION_5_23_0 = "5.23.0" 27 VERSION_5_22_0 = "5.22.0" 28 VERSION_5_21_0 = "5.21.0" 29 VERSION_5_20_0 = "5.20.0" 30 VERSION_5_19_0 = "5.19.0" 31 VERSION_5_18_0 = "5.18.0" 32 VERSION_5_17_0 = "5.17.0" 33 VERSION_5_16_0 = "5.16.0" 34 VERSION_5_15_0 = "5.15.0" 35 VERSION_5_14_0 = "5.14.0" 36 VERSION_5_13_0 = "5.13.0" 37 VERSION_5_12_0 = "5.12.0" 38 VERSION_5_11_0 = "5.11.0" 39 VERSION_5_10_0 = "5.10.0" 40 VERSION_5_9_0 = "5.9.0" 41 VERSION_5_8_0 = "5.8.0" 42 VERSION_5_7_0 = "5.7.0" 43 VERSION_5_6_0 = "5.6.0" 44 VERSION_5_5_0 = "5.5.0" 45 VERSION_5_4_0 = "5.4.0" 46 VERSION_5_3_0 = "5.3.0" 47 VERSION_5_2_0 = "5.2.0" 48 VERSION_5_1_0 = "5.1.0" 49 VERSION_5_0_0 = "5.0.0" 50 VERSION_4_10_0 = "4.10.0" 51 VERSION_4_9_0 = "4.9.0" 52 VERSION_4_8_1 = "4.8.1" 53 VERSION_4_8_0 = "4.8.0" 54 VERSION_4_7_2 = "4.7.2" 55 VERSION_4_7_1 = "4.7.1" 56 VERSION_4_7_0 = "4.7.0" 57 VERSION_4_6_0 = "4.6.0" 58 VERSION_4_5_0 = "4.5.0" 59 VERSION_4_4_0 = "4.4.0" 60 VERSION_4_3_0 = "4.3.0" 61 VERSION_4_2_0 = "4.2.0" 62 VERSION_4_1_0 = "4.1.0" 63 VERSION_4_0_0 = "4.0.0" 64 VERSION_3_10_0 = "3.10.0" 65 VERSION_3_9_0 = "3.9.0" 66 VERSION_3_8_0 = "3.8.0" 67 VERSION_3_7_0 = "3.7.0" 68 VERSION_3_6_0 = "3.6.0" 69 VERSION_3_5_0 = "3.5.0" 70 VERSION_3_4_0 = "3.4.0" 71 VERSION_3_3_0 = "3.3.0" 72 VERSION_3_2_0 = "3.2.0" 73 VERSION_3_1_0 = "3.1.0" 74 VERSION_3_0_0 = "3.0.0" 75 OLDEST_SUPPORTED_VERSION = VERSION_3_0_0 76 ) 77 78 const ( 79 EXIT_VERSION_SAVE = 1003 80 EXIT_THEME_MIGRATION = 1004 81 EXIT_TEAM_INVITEID_MIGRATION_FAILED = 1006 82 ) 83 84 // upgradeDatabase attempts to migrate the schema to the latest supported version. 85 // The value of model.CurrentVersion is accepted as a parameter for unit testing, but it is not 86 // used to stop migrations at that version. 87 func upgradeDatabase(sqlStore SqlStore, currentModelVersionString string) error { 88 currentModelVersion, err := semver.Parse(currentModelVersionString) 89 if err != nil { 90 return errors.Wrapf(err, "failed to parse current model version %s", currentModelVersionString) 91 } 92 93 nextUnsupportedMajorVersion := semver.Version{ 94 Major: currentModelVersion.Major + 1, 95 } 96 97 oldestSupportedVersion, err := semver.Parse(OLDEST_SUPPORTED_VERSION) 98 if err != nil { 99 return errors.Wrapf(err, "failed to parse oldest supported version %s", OLDEST_SUPPORTED_VERSION) 100 } 101 102 var currentSchemaVersion *semver.Version 103 currentSchemaVersionString := sqlStore.GetCurrentSchemaVersion() 104 if currentSchemaVersionString != "" { 105 currentSchemaVersion, err = semver.New(currentSchemaVersionString) 106 if err != nil { 107 return errors.Wrapf(err, "failed to parse database schema version %s", currentSchemaVersionString) 108 } 109 } 110 111 // Assume a fresh database if no schema version has been recorded. 112 if currentSchemaVersion == nil { 113 if err := sqlStore.System().SaveOrUpdate(&model.System{Name: "Version", Value: currentModelVersion.String()}); err != nil { 114 return errors.Wrap(err, "failed to initialize schema version for fresh database") 115 } 116 117 currentSchemaVersion = ¤tModelVersion 118 mlog.Info("The database schema version has been set", mlog.String("version", currentSchemaVersion.String())) 119 return nil 120 } 121 122 // Upgrades prior to the oldest supported version are not supported. 123 if currentSchemaVersion.LT(oldestSupportedVersion) { 124 return errors.Errorf("Database schema version %s is no longer supported. This Mattermost server supports automatic upgrades from schema version %s through schema version %s. Please manually upgrade to at least version %s before continuing.", *currentSchemaVersion, oldestSupportedVersion, currentModelVersion, oldestSupportedVersion) 125 } 126 127 // Allow forwards compatibility only within the same major version. 128 if currentSchemaVersion.GTE(nextUnsupportedMajorVersion) { 129 return errors.Errorf("Database schema version %s is not supported. This Mattermost server supports only >=%s, <%s. Please upgrade to at least version %s before continuing.", *currentSchemaVersion, currentModelVersion, nextUnsupportedMajorVersion, nextUnsupportedMajorVersion) 130 } else if currentSchemaVersion.GT(currentModelVersion) { 131 mlog.Warn("The database schema version and model versions do not match", mlog.String("schema_version", currentSchemaVersion.String()), mlog.String("model_version", currentModelVersion.String())) 132 } 133 134 // Otherwise, apply any necessary migrations. Note that these methods currently invoke 135 // os.Exit instead of returning an error. 136 upgradeDatabaseToVersion31(sqlStore) 137 upgradeDatabaseToVersion32(sqlStore) 138 upgradeDatabaseToVersion33(sqlStore) 139 upgradeDatabaseToVersion34(sqlStore) 140 upgradeDatabaseToVersion35(sqlStore) 141 upgradeDatabaseToVersion36(sqlStore) 142 upgradeDatabaseToVersion37(sqlStore) 143 upgradeDatabaseToVersion38(sqlStore) 144 upgradeDatabaseToVersion39(sqlStore) 145 upgradeDatabaseToVersion310(sqlStore) 146 upgradeDatabaseToVersion40(sqlStore) 147 upgradeDatabaseToVersion41(sqlStore) 148 upgradeDatabaseToVersion42(sqlStore) 149 upgradeDatabaseToVersion43(sqlStore) 150 upgradeDatabaseToVersion44(sqlStore) 151 upgradeDatabaseToVersion45(sqlStore) 152 upgradeDatabaseToVersion46(sqlStore) 153 upgradeDatabaseToVersion47(sqlStore) 154 upgradeDatabaseToVersion471(sqlStore) 155 upgradeDatabaseToVersion472(sqlStore) 156 upgradeDatabaseToVersion48(sqlStore) 157 upgradeDatabaseToVersion481(sqlStore) 158 upgradeDatabaseToVersion49(sqlStore) 159 upgradeDatabaseToVersion410(sqlStore) 160 upgradeDatabaseToVersion50(sqlStore) 161 upgradeDatabaseToVersion51(sqlStore) 162 upgradeDatabaseToVersion52(sqlStore) 163 upgradeDatabaseToVersion53(sqlStore) 164 upgradeDatabaseToVersion54(sqlStore) 165 upgradeDatabaseToVersion55(sqlStore) 166 upgradeDatabaseToVersion56(sqlStore) 167 upgradeDatabaseToVersion57(sqlStore) 168 upgradeDatabaseToVersion58(sqlStore) 169 upgradeDatabaseToVersion59(sqlStore) 170 upgradeDatabaseToVersion510(sqlStore) 171 upgradeDatabaseToVersion511(sqlStore) 172 upgradeDatabaseToVersion512(sqlStore) 173 upgradeDatabaseToVersion513(sqlStore) 174 upgradeDatabaseToVersion514(sqlStore) 175 upgradeDatabaseToVersion515(sqlStore) 176 upgradeDatabaseToVersion516(sqlStore) 177 upgradeDatabaseToVersion517(sqlStore) 178 upgradeDatabaseToVersion518(sqlStore) 179 upgradeDatabaseToVersion519(sqlStore) 180 upgradeDatabaseToVersion520(sqlStore) 181 upgradeDatabaseToVersion521(sqlStore) 182 upgradeDatabaseToVersion522(sqlStore) 183 upgradeDatabaseToVersion523(sqlStore) 184 upgradeDatabaseToVersion524(sqlStore) 185 upgradeDatabaseToVersion525(sqlStore) 186 upgradeDatabaseToVersion526(sqlStore) 187 upgradeDatabaseToVersion527(sqlStore) 188 189 return nil 190 } 191 192 func saveSchemaVersion(sqlStore SqlStore, version string) { 193 if err := sqlStore.System().SaveOrUpdate(&model.System{Name: "Version", Value: version}); err != nil { 194 mlog.Critical(err.Error()) 195 time.Sleep(time.Second) 196 os.Exit(EXIT_VERSION_SAVE) 197 } 198 199 mlog.Warn("The database schema version has been upgraded", mlog.String("version", version)) 200 } 201 202 func shouldPerformUpgrade(sqlStore SqlStore, currentSchemaVersion string, expectedSchemaVersion string) bool { 203 if sqlStore.GetCurrentSchemaVersion() == currentSchemaVersion { 204 mlog.Warn("Attempting to upgrade the database schema version", mlog.String("current_version", currentSchemaVersion), mlog.String("new_version", expectedSchemaVersion)) 205 206 return true 207 } 208 209 return false 210 } 211 212 func upgradeDatabaseToVersion31(sqlStore SqlStore) { 213 if shouldPerformUpgrade(sqlStore, VERSION_3_0_0, VERSION_3_1_0) { 214 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "") 215 saveSchemaVersion(sqlStore, VERSION_3_1_0) 216 } 217 } 218 219 func upgradeDatabaseToVersion32(sqlStore SqlStore) { 220 if shouldPerformUpgrade(sqlStore, VERSION_3_1_0, VERSION_3_2_0) { 221 sqlStore.CreateColumnIfNotExists("TeamMembers", "DeleteAt", "bigint(20)", "bigint", "0") 222 223 saveSchemaVersion(sqlStore, VERSION_3_2_0) 224 } 225 } 226 227 func themeMigrationFailed(err error) { 228 mlog.Critical("Failed to migrate User.ThemeProps to Preferences table", mlog.Err(err)) 229 time.Sleep(time.Second) 230 os.Exit(EXIT_THEME_MIGRATION) 231 } 232 233 func upgradeDatabaseToVersion33(sqlStore SqlStore) { 234 if shouldPerformUpgrade(sqlStore, VERSION_3_2_0, VERSION_3_3_0) { 235 if sqlStore.DoesColumnExist("Users", "ThemeProps") { 236 params := map[string]interface{}{ 237 "Category": model.PREFERENCE_CATEGORY_THEME, 238 "Name": "", 239 } 240 241 transaction, err := sqlStore.GetMaster().Begin() 242 if err != nil { 243 themeMigrationFailed(err) 244 } 245 defer finalizeTransaction(transaction) 246 247 // increase size of Value column of Preferences table to match the size of the ThemeProps column 248 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 249 if _, err := transaction.Exec("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil { 250 themeMigrationFailed(err) 251 return 252 } 253 } else if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL { 254 if _, err := transaction.Exec("ALTER TABLE Preferences MODIFY Value text"); err != nil { 255 themeMigrationFailed(err) 256 return 257 } 258 } 259 260 // copy data across 261 if _, err := transaction.Exec( 262 `INSERT INTO 263 Preferences(UserId, Category, Name, Value) 264 SELECT 265 Id, '`+model.PREFERENCE_CATEGORY_THEME+`', '', ThemeProps 266 FROM 267 Users 268 WHERE 269 Users.ThemeProps != 'null'`, params); err != nil { 270 themeMigrationFailed(err) 271 return 272 } 273 274 // delete old data 275 if _, err := transaction.Exec("ALTER TABLE Users DROP COLUMN ThemeProps"); err != nil { 276 themeMigrationFailed(err) 277 return 278 } 279 280 if err := transaction.Commit(); err != nil { 281 themeMigrationFailed(err) 282 return 283 } 284 285 // rename solarized_* code themes to solarized-* to match client changes in 3.0 286 var data model.Preferences 287 if _, err := sqlStore.GetMaster().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PREFERENCE_CATEGORY_THEME+"' AND Value LIKE '%solarized_%'"); err == nil { 288 for i := range data { 289 data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1) 290 } 291 292 sqlStore.Preference().Save(&data) 293 } 294 } 295 296 sqlStore.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0") 297 sqlStore.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "") 298 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "") 299 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "") 300 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0") 301 302 if sqlStore.DoesColumnExist("OAuthAccessData", "AuthCode") { 303 sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData") 304 sqlStore.RemoveColumnIfExists("OAuthAccessData", "AuthCode") 305 } 306 307 sqlStore.RemoveColumnIfExists("Users", "LastActivityAt") 308 sqlStore.RemoveColumnIfExists("Users", "LastPingAt") 309 310 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0") 311 312 saveSchemaVersion(sqlStore, VERSION_3_3_0) 313 } 314 } 315 316 func upgradeDatabaseToVersion34(sqlStore SqlStore) { 317 if shouldPerformUpgrade(sqlStore, VERSION_3_3_0, VERSION_3_4_0) { 318 sqlStore.CreateColumnIfNotExists("Status", "Manual", "BOOLEAN", "BOOLEAN", "0") 319 sqlStore.CreateColumnIfNotExists("Status", "ActiveChannel", "varchar(26)", "varchar(26)", "") 320 321 saveSchemaVersion(sqlStore, VERSION_3_4_0) 322 } 323 } 324 325 func upgradeDatabaseToVersion35(sqlStore SqlStore) { 326 if shouldPerformUpgrade(sqlStore, VERSION_3_4_0, VERSION_3_5_0) { 327 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user' WHERE Roles = ''") 328 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user system_admin' WHERE Roles = 'system_admin'") 329 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user' WHERE Roles = ''") 330 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user team_admin' WHERE Roles = 'admin'") 331 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user' WHERE Roles = ''") 332 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user channel_admin' WHERE Roles = 'admin'") 333 334 // The rest of the migration from Filenames -> FileIds is done lazily in api.GetFileInfosForPost 335 sqlStore.CreateColumnIfNotExists("Posts", "FileIds", "varchar(150)", "varchar(150)", "[]") 336 337 // Increase maximum length of the Channel table Purpose column. 338 if sqlStore.GetMaxLengthOfColumnIfExists("Channels", "Purpose") != "250" { 339 sqlStore.AlterColumnTypeIfExists("Channels", "Purpose", "varchar(250)", "varchar(250)") 340 } 341 342 sqlStore.Session().RemoveAllSessions() 343 344 saveSchemaVersion(sqlStore, VERSION_3_5_0) 345 } 346 } 347 348 func upgradeDatabaseToVersion36(sqlStore SqlStore) { 349 if shouldPerformUpgrade(sqlStore, VERSION_3_5_0, VERSION_3_6_0) { 350 sqlStore.CreateColumnIfNotExists("Posts", "HasReactions", "tinyint", "boolean", "0") 351 352 // Create Team Description column 353 sqlStore.CreateColumnIfNotExists("Teams", "Description", "varchar(255)", "varchar(255)", "") 354 355 // Add a Position column to users. 356 sqlStore.CreateColumnIfNotExists("Users", "Position", "varchar(64)", "varchar(64)", "") 357 358 // Remove ActiveChannel column from Status 359 sqlStore.RemoveColumnIfExists("Status", "ActiveChannel") 360 361 saveSchemaVersion(sqlStore, VERSION_3_6_0) 362 } 363 } 364 365 func upgradeDatabaseToVersion37(sqlStore SqlStore) { 366 if shouldPerformUpgrade(sqlStore, VERSION_3_6_0, VERSION_3_7_0) { 367 // Add EditAt column to Posts 368 sqlStore.CreateColumnIfNotExists("Posts", "EditAt", " bigint", " bigint", "0") 369 370 saveSchemaVersion(sqlStore, VERSION_3_7_0) 371 } 372 } 373 374 func upgradeDatabaseToVersion38(sqlStore SqlStore) { 375 if shouldPerformUpgrade(sqlStore, VERSION_3_7_0, VERSION_3_8_0) { 376 // Add the IsPinned column to posts. 377 sqlStore.CreateColumnIfNotExists("Posts", "IsPinned", "boolean", "boolean", "0") 378 379 saveSchemaVersion(sqlStore, VERSION_3_8_0) 380 } 381 } 382 383 func upgradeDatabaseToVersion39(sqlStore SqlStore) { 384 if shouldPerformUpgrade(sqlStore, VERSION_3_8_0, VERSION_3_9_0) { 385 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "Scope", "varchar(128)", "varchar(128)", model.DEFAULT_SCOPE) 386 sqlStore.RemoveTableIfExists("PasswordRecovery") 387 388 saveSchemaVersion(sqlStore, VERSION_3_9_0) 389 } 390 } 391 392 func upgradeDatabaseToVersion310(sqlStore SqlStore) { 393 if shouldPerformUpgrade(sqlStore, VERSION_3_9_0, VERSION_3_10_0) { 394 saveSchemaVersion(sqlStore, VERSION_3_10_0) 395 } 396 } 397 398 func upgradeDatabaseToVersion40(sqlStore SqlStore) { 399 if shouldPerformUpgrade(sqlStore, VERSION_3_10_0, VERSION_4_0_0) { 400 saveSchemaVersion(sqlStore, VERSION_4_0_0) 401 } 402 } 403 404 func upgradeDatabaseToVersion41(sqlStore SqlStore) { 405 if shouldPerformUpgrade(sqlStore, VERSION_4_0_0, VERSION_4_1_0) { 406 // Increase maximum length of the Users table Roles column. 407 if sqlStore.GetMaxLengthOfColumnIfExists("Users", "Roles") != "256" { 408 sqlStore.AlterColumnTypeIfExists("Users", "Roles", "varchar(256)", "varchar(256)") 409 } 410 411 sqlStore.RemoveTableIfExists("JobStatuses") 412 413 saveSchemaVersion(sqlStore, VERSION_4_1_0) 414 } 415 } 416 417 func upgradeDatabaseToVersion42(sqlStore SqlStore) { 418 if shouldPerformUpgrade(sqlStore, VERSION_4_1_0, VERSION_4_2_0) { 419 saveSchemaVersion(sqlStore, VERSION_4_2_0) 420 } 421 } 422 423 func upgradeDatabaseToVersion43(sqlStore SqlStore) { 424 if shouldPerformUpgrade(sqlStore, VERSION_4_2_0, VERSION_4_3_0) { 425 saveSchemaVersion(sqlStore, VERSION_4_3_0) 426 } 427 } 428 429 func upgradeDatabaseToVersion44(sqlStore SqlStore) { 430 if shouldPerformUpgrade(sqlStore, VERSION_4_3_0, VERSION_4_4_0) { 431 // Add the IsActive column to UserAccessToken. 432 sqlStore.CreateColumnIfNotExists("UserAccessTokens", "IsActive", "boolean", "boolean", "1") 433 434 saveSchemaVersion(sqlStore, VERSION_4_4_0) 435 } 436 } 437 438 func upgradeDatabaseToVersion45(sqlStore SqlStore) { 439 if shouldPerformUpgrade(sqlStore, VERSION_4_4_0, VERSION_4_5_0) { 440 saveSchemaVersion(sqlStore, VERSION_4_5_0) 441 } 442 } 443 444 func upgradeDatabaseToVersion46(sqlStore SqlStore) { 445 if shouldPerformUpgrade(sqlStore, VERSION_4_5_0, VERSION_4_6_0) { 446 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "Username", "varchar(64)", "varchar(64)", "") 447 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "") 448 saveSchemaVersion(sqlStore, VERSION_4_6_0) 449 } 450 } 451 452 func upgradeDatabaseToVersion47(sqlStore SqlStore) { 453 if shouldPerformUpgrade(sqlStore, VERSION_4_6_0, VERSION_4_7_0) { 454 sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)") 455 sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)") 456 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 457 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username") 458 saveSchemaVersion(sqlStore, VERSION_4_7_0) 459 } 460 } 461 462 func upgradeDatabaseToVersion471(sqlStore SqlStore) { 463 // If any new instances started with 4.7, they would have the bad Email column on the 464 // ChannelMemberHistory table. So for those cases we need to do an upgrade between 465 // 4.7.0 and 4.7.1 466 if shouldPerformUpgrade(sqlStore, VERSION_4_7_0, VERSION_4_7_1) { 467 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 468 saveSchemaVersion(sqlStore, VERSION_4_7_1) 469 } 470 } 471 472 func upgradeDatabaseToVersion472(sqlStore SqlStore) { 473 if shouldPerformUpgrade(sqlStore, VERSION_4_7_1, VERSION_4_7_2) { 474 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 475 saveSchemaVersion(sqlStore, VERSION_4_7_2) 476 } 477 } 478 479 func upgradeDatabaseToVersion48(sqlStore SqlStore) { 480 if shouldPerformUpgrade(sqlStore, VERSION_4_7_2, VERSION_4_8_0) { 481 saveSchemaVersion(sqlStore, VERSION_4_8_0) 482 } 483 } 484 485 func upgradeDatabaseToVersion481(sqlStore SqlStore) { 486 if shouldPerformUpgrade(sqlStore, VERSION_4_8_0, VERSION_4_8_1) { 487 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 488 saveSchemaVersion(sqlStore, VERSION_4_8_1) 489 } 490 } 491 492 func upgradeDatabaseToVersion49(sqlStore SqlStore) { 493 // This version of Mattermost includes an App-Layer migration which migrates from hard-coded roles configured by 494 // a number of parameters in `config.json` to a `Roles` table in the database. The migration code can be seen 495 // in the file `app/app.go` in the function `DoAdvancedPermissionsMigration()`. 496 497 if shouldPerformUpgrade(sqlStore, VERSION_4_8_1, VERSION_4_9_0) { 498 sqlStore.CreateColumnIfNotExists("Teams", "LastTeamIconUpdate", "bigint", "bigint", "0") 499 defaultTimezone := timezones.DefaultUserTimezone() 500 defaultTimezoneValue, err := json.Marshal(defaultTimezone) 501 if err != nil { 502 mlog.Critical(err.Error()) 503 } 504 sqlStore.CreateColumnIfNotExists("Users", "Timezone", "varchar(256)", "varchar(256)", string(defaultTimezoneValue)) 505 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 506 saveSchemaVersion(sqlStore, VERSION_4_9_0) 507 } 508 } 509 510 func upgradeDatabaseToVersion410(sqlStore SqlStore) { 511 if shouldPerformUpgrade(sqlStore, VERSION_4_9_0, VERSION_4_10_0) { 512 513 sqlStore.RemoveIndexIfExists("Name_2", "Channels") 514 sqlStore.RemoveIndexIfExists("Name_2", "Emoji") 515 sqlStore.RemoveIndexIfExists("ClientId_2", "OAuthAccessData") 516 517 saveSchemaVersion(sqlStore, VERSION_4_10_0) 518 sqlStore.GetMaster().Exec("UPDATE Users SET AuthData=LOWER(AuthData) WHERE AuthService = 'saml'") 519 } 520 } 521 522 func upgradeDatabaseToVersion50(sqlStore SqlStore) { 523 // This version of Mattermost includes an App-Layer migration which migrates from hard-coded emojis configured 524 // in `config.json` to a `Permission` in the database. The migration code can be seen 525 // in the file `app/app.go` in the function `DoEmojisPermissionsMigration()`. 526 527 // This version of Mattermost also includes a online-migration which migrates some roles from the `Roles` columns of 528 // TeamMember and ChannelMember rows to the new SchemeAdmin and SchemeUser columns. If you need to downgrade to a 529 // version of Mattermost prior to 5.0, you should take your server offline and run the following SQL statements 530 // prior to launching the downgraded version: 531 // 532 // UPDATE Teams SET SchemeId = NULL; 533 // UPDATE Channels SET SchemeId = NULL; 534 // UPDATE TeamMembers SET Roles = CONCAT(Roles, ' team_user'), SchemeUser = NULL where SchemeUser = 1; 535 // UPDATE TeamMembers SET Roles = CONCAT(Roles, ' team_admin'), SchemeAdmin = NULL where SchemeAdmin = 1; 536 // UPDATE ChannelMembers SET Roles = CONCAT(Roles, ' channel_user'), SchemeUser = NULL where SchemeUser = 1; 537 // UPDATE ChannelMembers SET Roles = CONCAT(Roles, ' channel_admin'), SchemeAdmin = NULL where SchemeAdmin = 1; 538 // DELETE from Systems WHERE Name = 'migration_advanced_permissions_phase_2'; 539 540 if shouldPerformUpgrade(sqlStore, VERSION_4_10_0, VERSION_5_0_0) { 541 542 sqlStore.CreateColumnIfNotExistsNoDefault("Teams", "SchemeId", "varchar(26)", "varchar(26)") 543 sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "SchemeId", "varchar(26)", "varchar(26)") 544 545 sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeUser", "boolean", "boolean") 546 sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeAdmin", "boolean", "boolean") 547 sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeUser", "boolean", "boolean") 548 sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeAdmin", "boolean", "boolean") 549 550 sqlStore.CreateColumnIfNotExists("Roles", "BuiltIn", "boolean", "boolean", "0") 551 sqlStore.GetMaster().Exec("UPDATE Roles SET BuiltIn=true") 552 sqlStore.GetMaster().Exec("UPDATE Roles SET SchemeManaged=false WHERE Name NOT IN ('system_user', 'system_admin', 'team_user', 'team_admin', 'channel_user', 'channel_admin')") 553 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "ChannelLocked", "boolean", "boolean", "0") 554 555 sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels") 556 557 saveSchemaVersion(sqlStore, VERSION_5_0_0) 558 } 559 } 560 561 func upgradeDatabaseToVersion51(sqlStore SqlStore) { 562 if shouldPerformUpgrade(sqlStore, VERSION_5_0_0, VERSION_5_1_0) { 563 saveSchemaVersion(sqlStore, VERSION_5_1_0) 564 } 565 } 566 567 func upgradeDatabaseToVersion52(sqlStore SqlStore) { 568 if shouldPerformUpgrade(sqlStore, VERSION_5_1_0, VERSION_5_2_0) { 569 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "Username", "varchar(64)", "varchar(64)", "") 570 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "") 571 saveSchemaVersion(sqlStore, VERSION_5_2_0) 572 } 573 } 574 575 func upgradeDatabaseToVersion53(sqlStore SqlStore) { 576 if shouldPerformUpgrade(sqlStore, VERSION_5_2_0, VERSION_5_3_0) { 577 saveSchemaVersion(sqlStore, VERSION_5_3_0) 578 } 579 } 580 581 func upgradeDatabaseToVersion54(sqlStore SqlStore) { 582 if shouldPerformUpgrade(sqlStore, VERSION_5_3_0, VERSION_5_4_0) { 583 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "varchar(500)", "varchar(500)") 584 sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Description", "varchar(500)", "varchar(500)") 585 if err := sqlStore.Channel().MigratePublicChannels(); err != nil { 586 mlog.Critical("Failed to migrate PublicChannels table", mlog.Err(err)) 587 time.Sleep(time.Second) 588 os.Exit(EXIT_GENERIC_FAILURE) 589 } 590 saveSchemaVersion(sqlStore, VERSION_5_4_0) 591 } 592 } 593 594 func upgradeDatabaseToVersion55(sqlStore SqlStore) { 595 if shouldPerformUpgrade(sqlStore, VERSION_5_4_0, VERSION_5_5_0) { 596 saveSchemaVersion(sqlStore, VERSION_5_5_0) 597 } 598 } 599 600 func upgradeDatabaseToVersion56(sqlStore SqlStore) { 601 if shouldPerformUpgrade(sqlStore, VERSION_5_5_0, VERSION_5_6_0) { 602 sqlStore.CreateColumnIfNotExists("PluginKeyValueStore", "ExpireAt", "bigint(20)", "bigint", "0") 603 604 // migrating user's accepted terms of service data into the new table 605 sqlStore.GetMaster().Exec("INSERT INTO UserTermsOfService SELECT Id, AcceptedTermsOfServiceId as TermsOfServiceId, :CreateAt FROM Users WHERE AcceptedTermsOfServiceId != \"\" AND AcceptedTermsOfServiceId IS NOT NULL", map[string]interface{}{"CreateAt": model.GetMillis()}) 606 607 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 608 sqlStore.RemoveIndexIfExists("idx_users_email_lower", "lower(Email)") 609 sqlStore.RemoveIndexIfExists("idx_users_username_lower", "lower(Username)") 610 sqlStore.RemoveIndexIfExists("idx_users_nickname_lower", "lower(Nickname)") 611 sqlStore.RemoveIndexIfExists("idx_users_firstname_lower", "lower(FirstName)") 612 sqlStore.RemoveIndexIfExists("idx_users_lastname_lower", "lower(LastName)") 613 } 614 615 saveSchemaVersion(sqlStore, VERSION_5_6_0) 616 } 617 618 } 619 620 func upgradeDatabaseToVersion57(sqlStore SqlStore) { 621 if shouldPerformUpgrade(sqlStore, VERSION_5_6_0, VERSION_5_7_0) { 622 saveSchemaVersion(sqlStore, VERSION_5_7_0) 623 } 624 } 625 626 func upgradeDatabaseToVersion58(sqlStore SqlStore) { 627 if shouldPerformUpgrade(sqlStore, VERSION_5_7_0, VERSION_5_8_0) { 628 // idx_channels_txt was removed in `upgradeDatabaseToVersion50`, but merged as part of 629 // v5.1, so the migration wouldn't apply to anyone upgrading from v5.0. Remove it again to 630 // bring the upgraded (from v5.0) and fresh install schemas back in sync. 631 sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels") 632 633 // Fix column types and defaults where gorp converged on a different schema value than the 634 // original migration. 635 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "text", "VARCHAR(500)") 636 sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Description", "text", "VARCHAR(500)") 637 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "IconURL", "text", "VARCHAR(1024)") 638 sqlStore.AlterColumnDefaultIfExists("OutgoingWebhooks", "Username", model.NewString("NULL"), model.NewString("")) 639 sqlStore.AlterColumnDefaultIfExists("OutgoingWebhooks", "IconURL", nil, model.NewString("")) 640 sqlStore.AlterColumnDefaultIfExists("PluginKeyValueStore", "ExpireAt", model.NewString("NULL"), model.NewString("NULL")) 641 642 saveSchemaVersion(sqlStore, VERSION_5_8_0) 643 } 644 } 645 646 func upgradeDatabaseToVersion59(sqlStore SqlStore) { 647 if shouldPerformUpgrade(sqlStore, VERSION_5_8_0, VERSION_5_9_0) { 648 saveSchemaVersion(sqlStore, VERSION_5_9_0) 649 } 650 } 651 652 func upgradeDatabaseToVersion510(sqlStore SqlStore) { 653 if shouldPerformUpgrade(sqlStore, VERSION_5_9_0, VERSION_5_10_0) { 654 sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "GroupConstrained", "tinyint(4)", "boolean") 655 sqlStore.CreateColumnIfNotExistsNoDefault("Teams", "GroupConstrained", "tinyint(4)", "boolean") 656 657 sqlStore.CreateIndexIfNotExists("idx_groupteams_teamid", "GroupTeams", "TeamId") 658 sqlStore.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId") 659 660 saveSchemaVersion(sqlStore, VERSION_5_10_0) 661 } 662 } 663 664 func upgradeDatabaseToVersion511(sqlStore SqlStore) { 665 if shouldPerformUpgrade(sqlStore, VERSION_5_10_0, VERSION_5_11_0) { 666 // Enforce all teams have an InviteID set 667 var teams []*model.Team 668 if _, err := sqlStore.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE InviteId = ''"); err != nil { 669 mlog.Error("Error fetching Teams without InviteID", mlog.Err(err)) 670 } else { 671 for _, team := range teams { 672 team.InviteId = model.NewId() 673 if _, err := sqlStore.Team().Update(team); err != nil { 674 mlog.Error("Error updating Team InviteIDs", mlog.String("team_id", team.Id), mlog.Err(err)) 675 } 676 } 677 } 678 679 saveSchemaVersion(sqlStore, VERSION_5_11_0) 680 } 681 } 682 683 func upgradeDatabaseToVersion512(sqlStore SqlStore) { 684 if shouldPerformUpgrade(sqlStore, VERSION_5_11_0, VERSION_5_12_0) { 685 sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeGuest", "boolean", "boolean") 686 sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeGuest", "boolean", "boolean") 687 sqlStore.CreateColumnIfNotExistsNoDefault("Schemes", "DefaultTeamGuestRole", "text", "VARCHAR(64)") 688 sqlStore.CreateColumnIfNotExistsNoDefault("Schemes", "DefaultChannelGuestRole", "text", "VARCHAR(64)") 689 690 sqlStore.GetMaster().Exec("UPDATE Schemes SET DefaultTeamGuestRole = '', DefaultChannelGuestRole = ''") 691 692 // Saturday, January 24, 2065 5:20:00 AM GMT. To remove all personal access token sessions. 693 sqlStore.GetMaster().Exec("DELETE FROM Sessions WHERE ExpiresAt > 3000000000000") 694 695 saveSchemaVersion(sqlStore, VERSION_5_12_0) 696 } 697 } 698 699 func upgradeDatabaseToVersion513(sqlStore SqlStore) { 700 if shouldPerformUpgrade(sqlStore, VERSION_5_12_0, VERSION_5_13_0) { 701 // The previous jobs ran once per minute, cluttering the Jobs table with somewhat useless entries. Clean that up. 702 sqlStore.GetMaster().Exec("DELETE FROM Jobs WHERE Type = 'plugins'") 703 704 saveSchemaVersion(sqlStore, VERSION_5_13_0) 705 } 706 } 707 708 func upgradeDatabaseToVersion514(sqlStore SqlStore) { 709 if shouldPerformUpgrade(sqlStore, VERSION_5_13_0, VERSION_5_14_0) { 710 saveSchemaVersion(sqlStore, VERSION_5_14_0) 711 } 712 } 713 714 func upgradeDatabaseToVersion515(sqlStore SqlStore) { 715 if shouldPerformUpgrade(sqlStore, VERSION_5_14_0, VERSION_5_15_0) { 716 saveSchemaVersion(sqlStore, VERSION_5_15_0) 717 } 718 } 719 720 func upgradeDatabaseToVersion516(sqlStore SqlStore) { 721 if shouldPerformUpgrade(sqlStore, VERSION_5_15_0, VERSION_5_16_0) { 722 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 723 sqlStore.GetMaster().Exec("ALTER TABLE Tokens ALTER COLUMN Extra TYPE varchar(2048)") 724 } else if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL { 725 sqlStore.GetMaster().Exec("ALTER TABLE Tokens MODIFY Extra text") 726 } 727 saveSchemaVersion(sqlStore, VERSION_5_16_0) 728 729 // Fix mismatches between the canonical and migrated schemas. 730 sqlStore.AlterColumnTypeIfExists("TeamMembers", "SchemeGuest", "tinyint(4)", "boolean") 731 sqlStore.AlterColumnTypeIfExists("Schemes", "DefaultTeamGuestRole", "varchar(64)", "VARCHAR(64)") 732 sqlStore.AlterColumnTypeIfExists("Schemes", "DefaultChannelGuestRole", "varchar(64)", "VARCHAR(64)") 733 sqlStore.AlterColumnTypeIfExists("Teams", "AllowedDomains", "text", "VARCHAR(1000)") 734 sqlStore.AlterColumnTypeIfExists("Channels", "GroupConstrained", "tinyint(1)", "boolean") 735 sqlStore.AlterColumnTypeIfExists("Teams", "GroupConstrained", "tinyint(1)", "boolean") 736 737 // One known mismatch remains: ChannelMembers.SchemeGuest. The requisite migration 738 // is left here for posterity, but we're avoiding fix this given the corresponding 739 // table rewrite in most MySQL and Postgres instances. 740 // sqlStore.AlterColumnTypeIfExists("ChannelMembers", "SchemeGuest", "tinyint(4)", "boolean") 741 742 sqlStore.CreateIndexIfNotExists("idx_groupteams_teamid", "GroupTeams", "TeamId") 743 sqlStore.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId") 744 } 745 } 746 747 func upgradeDatabaseToVersion517(sqlStore SqlStore) { 748 if shouldPerformUpgrade(sqlStore, VERSION_5_16_0, VERSION_5_17_0) { 749 saveSchemaVersion(sqlStore, VERSION_5_17_0) 750 } 751 } 752 753 func upgradeDatabaseToVersion518(sqlStore SqlStore) { 754 if shouldPerformUpgrade(sqlStore, VERSION_5_17_0, VERSION_5_18_0) { 755 saveSchemaVersion(sqlStore, VERSION_5_18_0) 756 } 757 } 758 759 func upgradeDatabaseToVersion519(sqlStore SqlStore) { 760 if shouldPerformUpgrade(sqlStore, VERSION_5_18_0, VERSION_5_19_0) { 761 saveSchemaVersion(sqlStore, VERSION_5_19_0) 762 } 763 } 764 765 func upgradeDatabaseToVersion520(sqlStore SqlStore) { 766 if shouldPerformUpgrade(sqlStore, VERSION_5_19_0, VERSION_5_20_0) { 767 sqlStore.CreateColumnIfNotExistsNoDefault("Bots", "LastIconUpdate", "bigint", "bigint") 768 769 sqlStore.CreateColumnIfNotExists("GroupTeams", "SchemeAdmin", "boolean", "boolean", "0") 770 sqlStore.CreateIndexIfNotExists("idx_groupteams_schemeadmin", "GroupTeams", "SchemeAdmin") 771 772 sqlStore.CreateColumnIfNotExists("GroupChannels", "SchemeAdmin", "boolean", "boolean", "0") 773 sqlStore.CreateIndexIfNotExists("idx_groupchannels_schemeadmin", "GroupChannels", "SchemeAdmin") 774 775 saveSchemaVersion(sqlStore, VERSION_5_20_0) 776 } 777 } 778 779 func upgradeDatabaseToVersion521(sqlStore SqlStore) { 780 if shouldPerformUpgrade(sqlStore, VERSION_5_20_0, VERSION_5_21_0) { 781 saveSchemaVersion(sqlStore, VERSION_5_21_0) 782 } 783 } 784 785 func upgradeDatabaseToVersion522(sqlStore SqlStore) { 786 if shouldPerformUpgrade(sqlStore, VERSION_5_21_0, VERSION_5_22_0) { 787 sqlStore.CreateIndexIfNotExists("idx_teams_scheme_id", "Teams", "SchemeId") 788 sqlStore.CreateIndexIfNotExists("idx_channels_scheme_id", "Channels", "SchemeId") 789 sqlStore.CreateIndexIfNotExists("idx_channels_scheme_id", "Channels", "SchemeId") 790 sqlStore.CreateIndexIfNotExists("idx_schemes_channel_guest_role", "Schemes", "DefaultChannelGuestRole") 791 sqlStore.CreateIndexIfNotExists("idx_schemes_channel_user_role", "Schemes", "DefaultChannelUserRole") 792 sqlStore.CreateIndexIfNotExists("idx_schemes_channel_admin_role", "Schemes", "DefaultChannelAdminRole") 793 794 saveSchemaVersion(sqlStore, VERSION_5_22_0) 795 } 796 } 797 798 func upgradeDatabaseToVersion523(sqlStore SqlStore) { 799 if shouldPerformUpgrade(sqlStore, VERSION_5_22_0, VERSION_5_23_0) { 800 saveSchemaVersion(sqlStore, VERSION_5_23_0) 801 } 802 } 803 804 func upgradeDatabaseToVersion524(sqlStore SqlStore) { 805 if shouldPerformUpgrade(sqlStore, VERSION_5_23_0, VERSION_5_24_0) { 806 sqlStore.CreateColumnIfNotExists("UserGroups", "AllowReference", "boolean", "boolean", "0") 807 sqlStore.GetMaster().Exec("UPDATE UserGroups SET Name = null, AllowReference = false") 808 sqlStore.AlterPrimaryKey("Reactions", []string{"PostId", "UserId", "EmojiName"}) 809 810 saveSchemaVersion(sqlStore, VERSION_5_24_0) 811 } 812 } 813 814 func upgradeDatabaseToVersion525(sqlStore SqlStore) { 815 if shouldPerformUpgrade(sqlStore, VERSION_5_24_0, VERSION_5_25_0) { 816 saveSchemaVersion(sqlStore, VERSION_5_25_0) 817 } 818 } 819 820 func upgradeDatabaseToVersion526(sqlStore SqlStore) { 821 if shouldPerformUpgrade(sqlStore, VERSION_5_25_0, VERSION_5_26_0) { 822 sqlStore.CreateColumnIfNotExists("Sessions", "ExpiredNotify", "boolean", "boolean", "0") 823 824 saveSchemaVersion(sqlStore, VERSION_5_26_0) 825 } 826 } 827 828 func upgradeDatabaseToVersion527(sqlStore SqlStore) { 829 // TODO: uncomment when the time arrive to upgrade the DB for 5.27 830 // if shouldPerformUpgrade(sqlStore, VERSION_5_26_0, VERSION_5_27_0) { 831 sqlStore.CreateColumnIfNotExistsNoDefault("Commands", "PluginId", "VARCHAR(190)", "VARCHAR(190)") 832 833 // saveSchemaVersion(sqlStore, VERSION_5_27_0) 834 // } 835 }