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