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