github.com/mad-app/mattermost-server@v5.11.1+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 "database/sql" 8 "encoding/json" 9 "fmt" 10 "os" 11 "strings" 12 "time" 13 14 "github.com/blang/semver" 15 "github.com/pkg/errors" 16 17 "github.com/mattermost/mattermost-server/mlog" 18 "github.com/mattermost/mattermost-server/model" 19 "github.com/mattermost/mattermost-server/services/timezones" 20 ) 21 22 const ( 23 VERSION_5_11_0 = "5.11.0" 24 VERSION_5_10_0 = "5.10.0" 25 VERSION_5_9_0 = "5.9.0" 26 VERSION_5_8_0 = "5.8.0" 27 VERSION_5_7_0 = "5.7.0" 28 VERSION_5_6_0 = "5.6.0" 29 VERSION_5_5_0 = "5.5.0" 30 VERSION_5_4_0 = "5.4.0" 31 VERSION_5_3_0 = "5.3.0" 32 VERSION_5_2_0 = "5.2.0" 33 VERSION_5_1_0 = "5.1.0" 34 VERSION_5_0_0 = "5.0.0" 35 VERSION_4_10_0 = "4.10.0" 36 VERSION_4_9_0 = "4.9.0" 37 VERSION_4_8_1 = "4.8.1" 38 VERSION_4_8_0 = "4.8.0" 39 VERSION_4_7_2 = "4.7.2" 40 VERSION_4_7_1 = "4.7.1" 41 VERSION_4_7_0 = "4.7.0" 42 VERSION_4_6_0 = "4.6.0" 43 VERSION_4_5_0 = "4.5.0" 44 VERSION_4_4_0 = "4.4.0" 45 VERSION_4_3_0 = "4.3.0" 46 VERSION_4_2_0 = "4.2.0" 47 VERSION_4_1_0 = "4.1.0" 48 VERSION_4_0_0 = "4.0.0" 49 VERSION_3_10_0 = "3.10.0" 50 VERSION_3_9_0 = "3.9.0" 51 VERSION_3_8_0 = "3.8.0" 52 VERSION_3_7_0 = "3.7.0" 53 VERSION_3_6_0 = "3.6.0" 54 VERSION_3_5_0 = "3.5.0" 55 VERSION_3_4_0 = "3.4.0" 56 VERSION_3_3_0 = "3.3.0" 57 VERSION_3_2_0 = "3.2.0" 58 VERSION_3_1_0 = "3.1.0" 59 VERSION_3_0_0 = "3.0.0" 60 OLDEST_SUPPORTED_VERSION = VERSION_3_0_0 61 ) 62 63 const ( 64 EXIT_VERSION_SAVE = 1003 65 EXIT_THEME_MIGRATION = 1004 66 EXIT_TEAM_INVITEID_MIGRATION_FAILED = 1006 67 ) 68 69 // UpgradeDatabase attempts to migrate the schema to the latest supported version. 70 // The value of model.CurrentVersion is accepted as a parameter for unit testing, but it is not 71 // used to stop migrations at that version. 72 func UpgradeDatabase(sqlStore SqlStore, currentModelVersionString string) error { 73 currentModelVersion, err := semver.Parse(currentModelVersionString) 74 if err != nil { 75 return errors.Wrapf(err, "failed to parse current model version %s", currentModelVersionString) 76 } 77 78 nextUnsupportedMajorVersion := semver.Version{ 79 Major: currentModelVersion.Major + 1, 80 } 81 82 oldestSupportedVersion, err := semver.Parse(OLDEST_SUPPORTED_VERSION) 83 if err != nil { 84 return errors.Wrapf(err, "failed to parse oldest supported version %s", OLDEST_SUPPORTED_VERSION) 85 } 86 87 var currentSchemaVersion *semver.Version 88 currentSchemaVersionString := sqlStore.GetCurrentSchemaVersion() 89 if currentSchemaVersionString != "" { 90 currentSchemaVersion, err = semver.New(currentSchemaVersionString) 91 if err != nil { 92 return errors.Wrapf(err, "failed to parse database schema version %s", currentSchemaVersionString) 93 } 94 } 95 96 // Assume a fresh database if no schema version has been recorded. 97 if currentSchemaVersion == nil { 98 if result := <-sqlStore.System().SaveOrUpdate(&model.System{Name: "Version", Value: currentModelVersion.String()}); result.Err != nil { 99 return errors.Wrap(err, "failed to initialize schema version for fresh database") 100 } 101 102 currentSchemaVersion = ¤tModelVersion 103 mlog.Info(fmt.Sprintf("The database schema has been set to version %s", *currentSchemaVersion)) 104 return nil 105 } 106 107 // Upgrades prior to the oldest supported version are not supported. 108 if currentSchemaVersion.LT(oldestSupportedVersion) { 109 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) 110 } 111 112 // Allow forwards compatibility only within the same major version. 113 if currentSchemaVersion.GTE(nextUnsupportedMajorVersion) { 114 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) 115 } else if currentSchemaVersion.GT(currentModelVersion) { 116 mlog.Warn(fmt.Sprintf("The database schema with version %s is newer than Mattermost version %s.", currentSchemaVersion, currentModelVersion)) 117 } 118 119 // Otherwise, apply any necessary migrations. Note that these methods currently invoke 120 // os.Exit instead of returning an error. 121 UpgradeDatabaseToVersion31(sqlStore) 122 UpgradeDatabaseToVersion32(sqlStore) 123 UpgradeDatabaseToVersion33(sqlStore) 124 UpgradeDatabaseToVersion34(sqlStore) 125 UpgradeDatabaseToVersion35(sqlStore) 126 UpgradeDatabaseToVersion36(sqlStore) 127 UpgradeDatabaseToVersion37(sqlStore) 128 UpgradeDatabaseToVersion38(sqlStore) 129 UpgradeDatabaseToVersion39(sqlStore) 130 UpgradeDatabaseToVersion310(sqlStore) 131 UpgradeDatabaseToVersion40(sqlStore) 132 UpgradeDatabaseToVersion41(sqlStore) 133 UpgradeDatabaseToVersion42(sqlStore) 134 UpgradeDatabaseToVersion43(sqlStore) 135 UpgradeDatabaseToVersion44(sqlStore) 136 UpgradeDatabaseToVersion45(sqlStore) 137 UpgradeDatabaseToVersion46(sqlStore) 138 UpgradeDatabaseToVersion47(sqlStore) 139 UpgradeDatabaseToVersion471(sqlStore) 140 UpgradeDatabaseToVersion472(sqlStore) 141 UpgradeDatabaseToVersion48(sqlStore) 142 UpgradeDatabaseToVersion481(sqlStore) 143 UpgradeDatabaseToVersion49(sqlStore) 144 UpgradeDatabaseToVersion410(sqlStore) 145 UpgradeDatabaseToVersion50(sqlStore) 146 UpgradeDatabaseToVersion51(sqlStore) 147 UpgradeDatabaseToVersion52(sqlStore) 148 UpgradeDatabaseToVersion53(sqlStore) 149 UpgradeDatabaseToVersion54(sqlStore) 150 UpgradeDatabaseToVersion55(sqlStore) 151 UpgradeDatabaseToVersion56(sqlStore) 152 UpgradeDatabaseToVersion57(sqlStore) 153 UpgradeDatabaseToVersion58(sqlStore) 154 UpgradeDatabaseToVersion59(sqlStore) 155 UpgradeDatabaseToVersion510(sqlStore) 156 UpgradeDatabaseToVersion511(sqlStore) 157 158 return nil 159 } 160 161 func saveSchemaVersion(sqlStore SqlStore, version string) { 162 if result := <-sqlStore.System().SaveOrUpdate(&model.System{Name: "Version", Value: version}); result.Err != nil { 163 mlog.Critical(result.Err.Error()) 164 time.Sleep(time.Second) 165 os.Exit(EXIT_VERSION_SAVE) 166 } 167 168 mlog.Warn(fmt.Sprintf("The database schema has been upgraded to version %v", version)) 169 } 170 171 func shouldPerformUpgrade(sqlStore SqlStore, currentSchemaVersion string, expectedSchemaVersion string) bool { 172 if sqlStore.GetCurrentSchemaVersion() == currentSchemaVersion { 173 mlog.Warn(fmt.Sprintf("Attempting to upgrade the database schema version from %s to %v", currentSchemaVersion, expectedSchemaVersion)) 174 175 return true 176 } 177 178 return false 179 } 180 181 func UpgradeDatabaseToVersion31(sqlStore SqlStore) { 182 if shouldPerformUpgrade(sqlStore, VERSION_3_0_0, VERSION_3_1_0) { 183 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "") 184 saveSchemaVersion(sqlStore, VERSION_3_1_0) 185 } 186 } 187 188 func UpgradeDatabaseToVersion32(sqlStore SqlStore) { 189 if shouldPerformUpgrade(sqlStore, VERSION_3_1_0, VERSION_3_2_0) { 190 sqlStore.CreateColumnIfNotExists("TeamMembers", "DeleteAt", "bigint(20)", "bigint", "0") 191 192 saveSchemaVersion(sqlStore, VERSION_3_2_0) 193 } 194 } 195 196 func themeMigrationFailed(err error) { 197 mlog.Critical(fmt.Sprintf("Failed to migrate User.ThemeProps to Preferences table %v", err)) 198 time.Sleep(time.Second) 199 os.Exit(EXIT_THEME_MIGRATION) 200 } 201 202 func UpgradeDatabaseToVersion33(sqlStore SqlStore) { 203 if shouldPerformUpgrade(sqlStore, VERSION_3_2_0, VERSION_3_3_0) { 204 if sqlStore.DoesColumnExist("Users", "ThemeProps") { 205 params := map[string]interface{}{ 206 "Category": model.PREFERENCE_CATEGORY_THEME, 207 "Name": "", 208 } 209 210 transaction, err := sqlStore.GetMaster().Begin() 211 if err != nil { 212 themeMigrationFailed(err) 213 } 214 defer finalizeTransaction(transaction) 215 216 // increase size of Value column of Preferences table to match the size of the ThemeProps column 217 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 218 if _, err := transaction.Exec("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil { 219 themeMigrationFailed(err) 220 return 221 } 222 } else if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL { 223 if _, err := transaction.Exec("ALTER TABLE Preferences MODIFY Value text"); err != nil { 224 themeMigrationFailed(err) 225 return 226 } 227 } 228 229 // copy data across 230 if _, err := transaction.Exec( 231 `INSERT INTO 232 Preferences(UserId, Category, Name, Value) 233 SELECT 234 Id, '`+model.PREFERENCE_CATEGORY_THEME+`', '', ThemeProps 235 FROM 236 Users 237 WHERE 238 Users.ThemeProps != 'null'`, params); err != nil { 239 themeMigrationFailed(err) 240 return 241 } 242 243 // delete old data 244 if _, err := transaction.Exec("ALTER TABLE Users DROP COLUMN ThemeProps"); err != nil { 245 themeMigrationFailed(err) 246 return 247 } 248 249 if err := transaction.Commit(); err != nil { 250 themeMigrationFailed(err) 251 return 252 } 253 254 // rename solarized_* code themes to solarized-* to match client changes in 3.0 255 var data model.Preferences 256 if _, err := sqlStore.GetMaster().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PREFERENCE_CATEGORY_THEME+"' AND Value LIKE '%solarized_%'"); err == nil { 257 for i := range data { 258 data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1) 259 } 260 261 sqlStore.Preference().Save(&data) 262 } 263 } 264 265 sqlStore.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0") 266 sqlStore.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "") 267 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "") 268 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "") 269 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0") 270 271 if sqlStore.DoesColumnExist("OAuthAccessData", "AuthCode") { 272 sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData") 273 sqlStore.RemoveColumnIfExists("OAuthAccessData", "AuthCode") 274 } 275 276 sqlStore.RemoveColumnIfExists("Users", "LastActivityAt") 277 sqlStore.RemoveColumnIfExists("Users", "LastPingAt") 278 279 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0") 280 281 saveSchemaVersion(sqlStore, VERSION_3_3_0) 282 } 283 } 284 285 func UpgradeDatabaseToVersion34(sqlStore SqlStore) { 286 if shouldPerformUpgrade(sqlStore, VERSION_3_3_0, VERSION_3_4_0) { 287 sqlStore.CreateColumnIfNotExists("Status", "Manual", "BOOLEAN", "BOOLEAN", "0") 288 sqlStore.CreateColumnIfNotExists("Status", "ActiveChannel", "varchar(26)", "varchar(26)", "") 289 290 saveSchemaVersion(sqlStore, VERSION_3_4_0) 291 } 292 } 293 294 func UpgradeDatabaseToVersion35(sqlStore SqlStore) { 295 if shouldPerformUpgrade(sqlStore, VERSION_3_4_0, VERSION_3_5_0) { 296 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user' WHERE Roles = ''") 297 sqlStore.GetMaster().Exec("UPDATE Users SET Roles = 'system_user system_admin' WHERE Roles = 'system_admin'") 298 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user' WHERE Roles = ''") 299 sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user team_admin' WHERE Roles = 'admin'") 300 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user' WHERE Roles = ''") 301 sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user channel_admin' WHERE Roles = 'admin'") 302 303 // The rest of the migration from Filenames -> FileIds is done lazily in api.GetFileInfosForPost 304 sqlStore.CreateColumnIfNotExists("Posts", "FileIds", "varchar(150)", "varchar(150)", "[]") 305 306 // Increase maximum length of the Channel table Purpose column. 307 if sqlStore.GetMaxLengthOfColumnIfExists("Channels", "Purpose") != "250" { 308 sqlStore.AlterColumnTypeIfExists("Channels", "Purpose", "varchar(250)", "varchar(250)") 309 } 310 311 sqlStore.Session().RemoveAllSessions() 312 313 saveSchemaVersion(sqlStore, VERSION_3_5_0) 314 } 315 } 316 317 func UpgradeDatabaseToVersion36(sqlStore SqlStore) { 318 if shouldPerformUpgrade(sqlStore, VERSION_3_5_0, VERSION_3_6_0) { 319 sqlStore.CreateColumnIfNotExists("Posts", "HasReactions", "tinyint", "boolean", "0") 320 321 // Create Team Description column 322 sqlStore.CreateColumnIfNotExists("Teams", "Description", "varchar(255)", "varchar(255)", "") 323 324 // Add a Position column to users. 325 sqlStore.CreateColumnIfNotExists("Users", "Position", "varchar(64)", "varchar(64)", "") 326 327 // Remove ActiveChannel column from Status 328 sqlStore.RemoveColumnIfExists("Status", "ActiveChannel") 329 330 saveSchemaVersion(sqlStore, VERSION_3_6_0) 331 } 332 } 333 334 func UpgradeDatabaseToVersion37(sqlStore SqlStore) { 335 if shouldPerformUpgrade(sqlStore, VERSION_3_6_0, VERSION_3_7_0) { 336 // Add EditAt column to Posts 337 sqlStore.CreateColumnIfNotExists("Posts", "EditAt", " bigint", " bigint", "0") 338 339 saveSchemaVersion(sqlStore, VERSION_3_7_0) 340 } 341 } 342 343 func UpgradeDatabaseToVersion38(sqlStore SqlStore) { 344 if shouldPerformUpgrade(sqlStore, VERSION_3_7_0, VERSION_3_8_0) { 345 // Add the IsPinned column to posts. 346 sqlStore.CreateColumnIfNotExists("Posts", "IsPinned", "boolean", "boolean", "0") 347 348 saveSchemaVersion(sqlStore, VERSION_3_8_0) 349 } 350 } 351 352 func UpgradeDatabaseToVersion39(sqlStore SqlStore) { 353 if shouldPerformUpgrade(sqlStore, VERSION_3_8_0, VERSION_3_9_0) { 354 sqlStore.CreateColumnIfNotExists("OAuthAccessData", "Scope", "varchar(128)", "varchar(128)", model.DEFAULT_SCOPE) 355 sqlStore.RemoveTableIfExists("PasswordRecovery") 356 357 saveSchemaVersion(sqlStore, VERSION_3_9_0) 358 } 359 } 360 361 func UpgradeDatabaseToVersion310(sqlStore SqlStore) { 362 if shouldPerformUpgrade(sqlStore, VERSION_3_9_0, VERSION_3_10_0) { 363 saveSchemaVersion(sqlStore, VERSION_3_10_0) 364 } 365 } 366 367 func UpgradeDatabaseToVersion40(sqlStore SqlStore) { 368 if shouldPerformUpgrade(sqlStore, VERSION_3_10_0, VERSION_4_0_0) { 369 saveSchemaVersion(sqlStore, VERSION_4_0_0) 370 } 371 } 372 373 func UpgradeDatabaseToVersion41(sqlStore SqlStore) { 374 if shouldPerformUpgrade(sqlStore, VERSION_4_0_0, VERSION_4_1_0) { 375 // Increase maximum length of the Users table Roles column. 376 if sqlStore.GetMaxLengthOfColumnIfExists("Users", "Roles") != "256" { 377 sqlStore.AlterColumnTypeIfExists("Users", "Roles", "varchar(256)", "varchar(256)") 378 } 379 380 sqlStore.RemoveTableIfExists("JobStatuses") 381 382 saveSchemaVersion(sqlStore, VERSION_4_1_0) 383 } 384 } 385 386 func UpgradeDatabaseToVersion42(sqlStore SqlStore) { 387 if shouldPerformUpgrade(sqlStore, VERSION_4_1_0, VERSION_4_2_0) { 388 saveSchemaVersion(sqlStore, VERSION_4_2_0) 389 } 390 } 391 392 func UpgradeDatabaseToVersion43(sqlStore SqlStore) { 393 if shouldPerformUpgrade(sqlStore, VERSION_4_2_0, VERSION_4_3_0) { 394 saveSchemaVersion(sqlStore, VERSION_4_3_0) 395 } 396 } 397 398 func UpgradeDatabaseToVersion44(sqlStore SqlStore) { 399 if shouldPerformUpgrade(sqlStore, VERSION_4_3_0, VERSION_4_4_0) { 400 // Add the IsActive column to UserAccessToken. 401 sqlStore.CreateColumnIfNotExists("UserAccessTokens", "IsActive", "boolean", "boolean", "1") 402 403 saveSchemaVersion(sqlStore, VERSION_4_4_0) 404 } 405 } 406 407 func UpgradeDatabaseToVersion45(sqlStore SqlStore) { 408 if shouldPerformUpgrade(sqlStore, VERSION_4_4_0, VERSION_4_5_0) { 409 saveSchemaVersion(sqlStore, VERSION_4_5_0) 410 } 411 } 412 413 func UpgradeDatabaseToVersion46(sqlStore SqlStore) { 414 if shouldPerformUpgrade(sqlStore, VERSION_4_5_0, VERSION_4_6_0) { 415 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "Username", "varchar(64)", "varchar(64)", "") 416 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "") 417 saveSchemaVersion(sqlStore, VERSION_4_6_0) 418 } 419 } 420 421 func UpgradeDatabaseToVersion47(sqlStore SqlStore) { 422 if shouldPerformUpgrade(sqlStore, VERSION_4_6_0, VERSION_4_7_0) { 423 sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)") 424 sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)") 425 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 426 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username") 427 saveSchemaVersion(sqlStore, VERSION_4_7_0) 428 } 429 } 430 431 // If any new instances started with 4.7, they would have the bad Email column on the 432 // ChannelMemberHistory table. So for those cases we need to do an upgrade between 433 // 4.7.0 and 4.7.1 434 func UpgradeDatabaseToVersion471(sqlStore SqlStore) { 435 if shouldPerformUpgrade(sqlStore, VERSION_4_7_0, VERSION_4_7_1) { 436 sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") 437 saveSchemaVersion(sqlStore, VERSION_4_7_1) 438 } 439 } 440 441 func UpgradeDatabaseToVersion472(sqlStore SqlStore) { 442 if shouldPerformUpgrade(sqlStore, VERSION_4_7_1, VERSION_4_7_2) { 443 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 444 saveSchemaVersion(sqlStore, VERSION_4_7_2) 445 } 446 } 447 448 func UpgradeDatabaseToVersion48(sqlStore SqlStore) { 449 if shouldPerformUpgrade(sqlStore, VERSION_4_7_2, VERSION_4_8_0) { 450 saveSchemaVersion(sqlStore, VERSION_4_8_0) 451 } 452 } 453 454 func UpgradeDatabaseToVersion481(sqlStore SqlStore) { 455 if shouldPerformUpgrade(sqlStore, VERSION_4_8_0, VERSION_4_8_1) { 456 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 457 saveSchemaVersion(sqlStore, VERSION_4_8_1) 458 } 459 } 460 461 func UpgradeDatabaseToVersion49(sqlStore SqlStore) { 462 // This version of Mattermost includes an App-Layer migration which migrates from hard-coded roles configured by 463 // a number of parameters in `config.json` to a `Roles` table in the database. The migration code can be seen 464 // in the file `app/app.go` in the function `DoAdvancedPermissionsMigration()`. 465 466 if shouldPerformUpgrade(sqlStore, VERSION_4_8_1, VERSION_4_9_0) { 467 sqlStore.CreateColumnIfNotExists("Teams", "LastTeamIconUpdate", "bigint", "bigint", "0") 468 defaultTimezone := timezones.DefaultUserTimezone() 469 defaultTimezoneValue, err := json.Marshal(defaultTimezone) 470 if err != nil { 471 mlog.Critical(fmt.Sprint(err)) 472 } 473 sqlStore.CreateColumnIfNotExists("Users", "Timezone", "varchar(256)", "varchar(256)", string(defaultTimezoneValue)) 474 sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels") 475 saveSchemaVersion(sqlStore, VERSION_4_9_0) 476 } 477 } 478 479 func UpgradeDatabaseToVersion410(sqlStore SqlStore) { 480 if shouldPerformUpgrade(sqlStore, VERSION_4_9_0, VERSION_4_10_0) { 481 482 sqlStore.RemoveIndexIfExists("Name_2", "Channels") 483 sqlStore.RemoveIndexIfExists("Name_2", "Emoji") 484 sqlStore.RemoveIndexIfExists("ClientId_2", "OAuthAccessData") 485 486 saveSchemaVersion(sqlStore, VERSION_4_10_0) 487 sqlStore.GetMaster().Exec("UPDATE Users SET AuthData=LOWER(AuthData) WHERE AuthService = 'saml'") 488 } 489 } 490 491 func UpgradeDatabaseToVersion50(sqlStore SqlStore) { 492 // This version of Mattermost includes an App-Layer migration which migrates from hard-coded emojis configured 493 // in `config.json` to a `Permission` in the database. The migration code can be seen 494 // in the file `app/app.go` in the function `DoEmojisPermissionsMigration()`. 495 496 // This version of Mattermost also includes a online-migration which migrates some roles from the `Roles` columns of 497 // TeamMember and ChannelMember rows to the new SchemeAdmin and SchemeUser columns. If you need to downgrade to a 498 // version of Mattermost prior to 5.0, you should take your server offline and run the following SQL statements 499 // prior to launching the downgraded version: 500 // 501 // UPDATE Teams SET SchemeId = NULL; 502 // UPDATE Channels SET SchemeId = NULL; 503 // UPDATE TeamMembers SET Roles = CONCAT(Roles, ' team_user'), SchemeUser = NULL where SchemeUser = 1; 504 // UPDATE TeamMembers SET Roles = CONCAT(Roles, ' team_admin'), SchemeAdmin = NULL where SchemeAdmin = 1; 505 // UPDATE ChannelMembers SET Roles = CONCAT(Roles, ' channel_user'), SchemeUser = NULL where SchemeUser = 1; 506 // UPDATE ChannelMembers SET Roles = CONCAT(Roles, ' channel_admin'), SchemeAdmin = NULL where SchemeAdmin = 1; 507 // DELETE from Systems WHERE Name = 'migration_advanced_permissions_phase_2'; 508 509 if shouldPerformUpgrade(sqlStore, VERSION_4_10_0, VERSION_5_0_0) { 510 511 sqlStore.CreateColumnIfNotExistsNoDefault("Teams", "SchemeId", "varchar(26)", "varchar(26)") 512 sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "SchemeId", "varchar(26)", "varchar(26)") 513 514 sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeUser", "boolean", "boolean") 515 sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeAdmin", "boolean", "boolean") 516 sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeUser", "boolean", "boolean") 517 sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeAdmin", "boolean", "boolean") 518 519 sqlStore.CreateColumnIfNotExists("Roles", "BuiltIn", "boolean", "boolean", "0") 520 sqlStore.GetMaster().Exec("UPDATE Roles SET BuiltIn=true") 521 sqlStore.GetMaster().Exec("UPDATE Roles SET SchemeManaged=false WHERE Name NOT IN ('system_user', 'system_admin', 'team_user', 'team_admin', 'channel_user', 'channel_admin')") 522 sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "ChannelLocked", "boolean", "boolean", "0") 523 524 sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels") 525 526 saveSchemaVersion(sqlStore, VERSION_5_0_0) 527 } 528 } 529 530 func UpgradeDatabaseToVersion51(sqlStore SqlStore) { 531 if shouldPerformUpgrade(sqlStore, VERSION_5_0_0, VERSION_5_1_0) { 532 saveSchemaVersion(sqlStore, VERSION_5_1_0) 533 } 534 } 535 536 func UpgradeDatabaseToVersion52(sqlStore SqlStore) { 537 if shouldPerformUpgrade(sqlStore, VERSION_5_1_0, VERSION_5_2_0) { 538 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "Username", "varchar(64)", "varchar(64)", "") 539 sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "") 540 saveSchemaVersion(sqlStore, VERSION_5_2_0) 541 } 542 } 543 544 func UpgradeDatabaseToVersion53(sqlStore SqlStore) { 545 if shouldPerformUpgrade(sqlStore, VERSION_5_2_0, VERSION_5_3_0) { 546 saveSchemaVersion(sqlStore, VERSION_5_3_0) 547 } 548 } 549 550 func UpgradeDatabaseToVersion54(sqlStore SqlStore) { 551 if shouldPerformUpgrade(sqlStore, VERSION_5_3_0, VERSION_5_4_0) { 552 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "varchar(500)", "varchar(500)") 553 sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Description", "varchar(500)", "varchar(500)") 554 if err := sqlStore.Channel().MigratePublicChannels(); err != nil { 555 mlog.Critical("Failed to migrate PublicChannels table", mlog.Err(err)) 556 time.Sleep(time.Second) 557 os.Exit(EXIT_GENERIC_FAILURE) 558 } 559 saveSchemaVersion(sqlStore, VERSION_5_4_0) 560 } 561 } 562 563 func UpgradeDatabaseToVersion55(sqlStore SqlStore) { 564 if shouldPerformUpgrade(sqlStore, VERSION_5_4_0, VERSION_5_5_0) { 565 saveSchemaVersion(sqlStore, VERSION_5_5_0) 566 } 567 } 568 569 func UpgradeDatabaseToVersion56(sqlStore SqlStore) { 570 if shouldPerformUpgrade(sqlStore, VERSION_5_5_0, VERSION_5_6_0) { 571 sqlStore.CreateColumnIfNotExists("PluginKeyValueStore", "ExpireAt", "bigint(20)", "bigint", "0") 572 573 // migrating user's accepted terms of service data into the new table 574 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()}) 575 576 if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES { 577 sqlStore.RemoveIndexIfExists("idx_users_email_lower", "lower(Email)") 578 sqlStore.RemoveIndexIfExists("idx_users_username_lower", "lower(Username)") 579 sqlStore.RemoveIndexIfExists("idx_users_nickname_lower", "lower(Nickname)") 580 sqlStore.RemoveIndexIfExists("idx_users_firstname_lower", "lower(FirstName)") 581 sqlStore.RemoveIndexIfExists("idx_users_lastname_lower", "lower(LastName)") 582 } 583 584 saveSchemaVersion(sqlStore, VERSION_5_6_0) 585 } 586 587 } 588 589 func UpgradeDatabaseToVersion57(sqlStore SqlStore) { 590 if shouldPerformUpgrade(sqlStore, VERSION_5_6_0, VERSION_5_7_0) { 591 saveSchemaVersion(sqlStore, VERSION_5_7_0) 592 } 593 } 594 595 func getRole(sqlStore SqlStore, name string) (*model.Role, error) { 596 var dbRole Role 597 598 if err := sqlStore.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil { 599 if err == sql.ErrNoRows { 600 return nil, errors.Wrapf(err, "failed to find role %s", name) 601 } else { 602 return nil, errors.Wrapf(err, "failed to query role %s", name) 603 } 604 } 605 606 return dbRole.ToModel(), nil 607 } 608 609 func saveRole(sqlStore SqlStore, role *model.Role) error { 610 dbRole := NewRoleFromModel(role) 611 612 dbRole.UpdateAt = model.GetMillis() 613 if rowsChanged, err := sqlStore.GetMaster().Update(dbRole); err != nil { 614 return errors.Wrap(err, "failed to update role") 615 } else if rowsChanged != 1 { 616 return errors.New("found no role to update") 617 } 618 619 return nil 620 } 621 622 func UpgradeDatabaseToVersion58(sqlStore SqlStore) { 623 if shouldPerformUpgrade(sqlStore, VERSION_5_7_0, VERSION_5_8_0) { 624 // idx_channels_txt was removed in `UpgradeDatabaseToVersion50`, but merged as part of 625 // v5.1, so the migration wouldn't apply to anyone upgrading from v5.0. Remove it again to 626 // bring the upgraded (from v5.0) and fresh install schemas back in sync. 627 sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels") 628 629 // Fix column types and defaults where gorp converged on a different schema value than the 630 // original migration. 631 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "text", "VARCHAR(500)") 632 sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Description", "text", "VARCHAR(500)") 633 sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "IconURL", "text", "VARCHAR(1024)") 634 sqlStore.AlterColumnDefaultIfExists("OutgoingWebhooks", "Username", model.NewString("NULL"), model.NewString("")) 635 sqlStore.AlterColumnDefaultIfExists("OutgoingWebhooks", "IconURL", nil, model.NewString("")) 636 sqlStore.AlterColumnDefaultIfExists("PluginKeyValueStore", "ExpireAt", model.NewString("NULL"), model.NewString("NULL")) 637 638 saveSchemaVersion(sqlStore, VERSION_5_8_0) 639 } 640 } 641 642 func UpgradeDatabaseToVersion59(sqlStore SqlStore) { 643 if shouldPerformUpgrade(sqlStore, VERSION_5_8_0, VERSION_5_9_0) { 644 saveSchemaVersion(sqlStore, VERSION_5_9_0) 645 } 646 } 647 648 func UpgradeDatabaseToVersion510(sqlStore SqlStore) { 649 if shouldPerformUpgrade(sqlStore, VERSION_5_9_0, VERSION_5_10_0) { 650 sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "GroupConstrained", "tinyint(4)", "boolean") 651 sqlStore.CreateColumnIfNotExistsNoDefault("Teams", "GroupConstrained", "tinyint(4)", "boolean") 652 653 saveSchemaVersion(sqlStore, VERSION_5_10_0) 654 } 655 } 656 657 func UpgradeDatabaseToVersion511(sqlStore SqlStore) { 658 if shouldPerformUpgrade(sqlStore, VERSION_5_10_0, VERSION_5_11_0) { 659 // Enforce all teams have an InviteID set 660 var teams []*model.Team 661 if _, err := sqlStore.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE InviteId = ''"); err != nil { 662 mlog.Error("Error fetching Teams without InviteID: " + err.Error()) 663 } else { 664 for _, team := range teams { 665 team.InviteId = model.NewId() 666 if res := <-sqlStore.Team().Update(team); res.Err != nil { 667 mlog.Error("Error updating Team InviteIDs: " + res.Err.Error()) 668 } 669 } 670 } 671 672 saveSchemaVersion(sqlStore, VERSION_5_11_0) 673 } 674 }