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