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