summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Hulen <corey@hulen.com>2016-08-24 16:17:40 -0800
committerGitHub <noreply@github.com>2016-08-24 16:17:40 -0800
commitc3ae3f20f58b25aa6aba480ddc2239fd09e610cb (patch)
tree244c273ddb2fc7ed3ff2df2aee3a615aa5d61f28
parent8efa4dc9a5156c511aae8e3984795e55d4b7947f (diff)
downloadchat-c3ae3f20f58b25aa6aba480ddc2239fd09e610cb.tar.gz
chat-c3ae3f20f58b25aa6aba480ddc2239fd09e610cb.tar.bz2
chat-c3ae3f20f58b25aa6aba480ddc2239fd09e610cb.zip
PLT-3695 refactoring to use sql_upgrader (#3788)
* PLT-3695 unitying upgrade support * PLT-3695 refactoring to use sql_upgrader * Fixing unit test * Adding 3.3 to 3.4 * Fixing upgrading * Seperating DB schema from version.go * Fixing upgrade cmd * Moving to const for exit codes * remving old unused code
-rw-r--r--config/config.json2
-rw-r--r--mattermost.go338
-rw-r--r--store/sql_audit_store.go3
-rw-r--r--store/sql_channel_store.go3
-rw-r--r--store/sql_command_store.go4
-rw-r--r--store/sql_compliance_store.go3
-rw-r--r--store/sql_emoji_store.go3
-rw-r--r--store/sql_license_store.go3
-rw-r--r--store/sql_oauth_store.go14
-rw-r--r--store/sql_post_store.go3
-rw-r--r--store/sql_preference_store.go3
-rw-r--r--store/sql_recovery_store.go3
-rw-r--r--store/sql_session_store.go8
-rw-r--r--store/sql_status_store.go3
-rw-r--r--store/sql_store.go177
-rw-r--r--store/sql_store_test.go28
-rw-r--r--store/sql_system_store.go3
-rw-r--r--store/sql_team_store.go4
-rw-r--r--store/sql_upgrade.go190
-rw-r--r--store/sql_user_store.go73
-rw-r--r--store/sql_webhook_store.go10
21 files changed, 250 insertions, 628 deletions
diff --git a/config/config.json b/config/config.json
index 8374e695b..56ced04b5 100644
--- a/config/config.json
+++ b/config/config.json
@@ -220,4 +220,4 @@
"InterNodeListenAddress": ":8075",
"InterNodeUrls": []
}
-}
+} \ No newline at end of file
diff --git a/mattermost.go b/mattermost.go
index d3007f01b..be824e996 100644
--- a/mattermost.go
+++ b/mattermost.go
@@ -7,7 +7,6 @@ import (
"bufio"
"flag"
"fmt"
- "html/template"
"io/ioutil"
"net/http"
"net/url"
@@ -117,8 +116,6 @@ func main() {
*utils.Cfg.ServiceSettings.EnableDeveloper = true
}
- // Special case for upgrading the db to 3.0
- // ADDED for 3.0 REMOVE for 3.4
cmdUpdateDb30()
api.NewServer()
@@ -436,346 +433,13 @@ func cmdRunClientTests() {
}
}
-// ADDED for 3.0 REMOVE for 3.4
func cmdUpdateDb30() {
if flagCmdUpdateDb30 {
- api.Srv = &api.Server{}
- api.Srv.Store = store.NewSqlStoreForUpgrade30()
- store := api.Srv.Store.(*store.SqlStore)
- utils.InitHTML()
-
- l4g.Info("Attempting to run special upgrade of the database schema to version 3.0 for user model changes")
- time.Sleep(time.Second)
-
- if !store.DoesColumnExist("Users", "TeamId") {
- fmt.Println("**WARNING** the database schema appears to be upgraded to 3.0")
- flushLogAndExit(1)
- }
-
- if !(store.SchemaVersion == "2.2.0" ||
- store.SchemaVersion == "2.1.0" ||
- store.SchemaVersion == "2.0.0") {
- fmt.Println("**WARNING** the database schema needs to be version 2.2.0, 2.1.0 or 2.0.0 to upgrade")
- flushLogAndExit(1)
- }
-
- fmt.Println("\nPlease see http://www.mattermost.org/upgrade-to-3-0/")
- fmt.Println("**WARNING** This upgrade process will be irreversible.")
-
- if len(flagConfirmBackup) == 0 {
- fmt.Print("Have you performed a database backup? (YES/NO): ")
- fmt.Scanln(&flagConfirmBackup)
- }
-
- if flagConfirmBackup != "YES" {
- fmt.Fprintln(os.Stderr, "ABORTED: You did not answer YES exactly, in all capitals.")
- flushLogAndExit(1)
- }
-
- var teams []*TeamForUpgrade
-
- if _, err := store.GetMaster().Select(&teams, "SELECT Id, Name FROM Teams"); err != nil {
- l4g.Error("Failed to load all teams details=%v", err)
- flushLogAndExit(1)
- }
-
- if len(flagTeamName) == 0 {
- fmt.Println(fmt.Sprintf("We found %v teams.", len(teams)))
-
- for _, team := range teams {
- fmt.Println(team.Name)
- }
-
- fmt.Print("Please pick a primary team from the list above: ")
- fmt.Scanln(&flagTeamName)
- }
-
- var team *TeamForUpgrade
- for _, t := range teams {
- if t.Name == flagTeamName {
- team = t
- break
- }
- }
-
- if team == nil {
- l4g.Error("Failed to find primary team details")
- flushLogAndExit(1)
- }
-
- l4g.Info("Starting special 3.0 database upgrade with performed_backup=YES team_name=%v", team.Name)
- l4g.Info("Primary team %v will be left unchanged", team.Name)
- l4g.Info("Upgrading primary team %v", team.Name)
-
- uniqueEmails := make(map[string]bool)
- uniqueUsernames := make(map[string]bool)
- uniqueAuths := make(map[string]bool)
- primaryUsers := convertTeamTo30(team.Name, team, uniqueEmails, uniqueUsernames, uniqueAuths)
-
- l4g.Info("Upgraded %v users", len(primaryUsers))
-
- for _, otherTeam := range teams {
- if otherTeam.Id != team.Id {
- l4g.Info("Upgrading team %v", otherTeam.Name)
- users := convertTeamTo30(team.Name, otherTeam, uniqueEmails, uniqueUsernames, uniqueAuths)
- l4g.Info("Upgraded %v users", len(users))
-
- }
- }
-
- l4g.Info("Altering other scheme changes needed 3.0 for user model changes")
-
- if _, err := store.GetMaster().Exec(`
- UPDATE Channels
- SET
- TeamId = ''
- WHERE
- Type = 'D'
- `,
- ); err != nil {
- l4g.Error("Failed to update direct channel types details=%v", err)
- flushLogAndExit(1)
- }
-
- if _, err := store.GetMaster().Exec(`
- UPDATE Users
- SET
- AuthData = NULL
- WHERE
- AuthData = ''
- `,
- ); err != nil {
- l4g.Error("Failed to update AuthData types details=%v", err)
- flushLogAndExit(1)
- }
-
- extraLength := store.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
- if len(extraLength) > 0 && extraLength != "1024" {
- store.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
- }
-
- actionLength := store.GetMaxLengthOfColumnIfExists("Audits", "Action")
- if len(actionLength) > 0 && actionLength != "512" {
- store.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
- }
-
- if store.DoesColumnExist("Sessions", "TeamId") {
- store.RemoveColumnIfExists("Sessions", "TeamId")
- store.GetMaster().Exec(`TRUNCATE Sessions`)
- }
-
- // ADDED for 2.2 REMOVE for 2.6
- store.CreateColumnIfNotExists("Users", "MfaActive", "tinyint(1)", "boolean", "0")
- store.CreateColumnIfNotExists("Users", "MfaSecret", "varchar(128)", "character varying(128)", "")
-
- // ADDED for 2.2 REMOVE for 2.6
- if store.DoesColumnExist("Users", "TeamId") {
- store.RemoveIndexIfExists("idx_users_team_id", "Users")
- store.CreateUniqueIndexIfNotExists("idx_users_email_unique", "Users", "Email")
- store.CreateUniqueIndexIfNotExists("idx_users_username_unique", "Users", "Username")
- store.CreateUniqueIndexIfNotExists("idx_users_authdata_unique", "Users", "AuthData")
- store.RemoveColumnIfExists("Teams", "AllowTeamListing")
- store.RemoveColumnIfExists("Users", "TeamId")
- }
-
- l4g.Info("Finished running special upgrade of the database schema to version 3.0 for user model changes")
-
- if result := <-store.System().Update(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
- l4g.Error("Failed to update system schema version details=%v", result.Err)
- flushLogAndExit(1)
- }
-
- l4g.Info(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
- fmt.Println("**SUCCESS** with upgrade")
-
+ // This command is a no-op for backwards compatibility
flushLogAndExit(0)
}
}
-type UserForUpgrade struct {
- Id string
- Username string
- Email string
- Roles string
- TeamId string
- AuthData *string
-}
-
-func convertTeamTo30(primaryTeamName string, team *TeamForUpgrade, uniqueEmails map[string]bool, uniqueUsernames map[string]bool, uniqueAuths map[string]bool) []*UserForUpgrade {
- store := api.Srv.Store.(*store.SqlStore)
- var users []*UserForUpgrade
- if _, err := store.GetMaster().Select(&users, "SELECT Users.Id, Users.Username, Users.Email, Users.Roles, Users.TeamId, Users.AuthData FROM Users WHERE Users.TeamId = :TeamId", map[string]interface{}{"TeamId": team.Id}); err != nil {
- l4g.Error("Failed to load profiles for team details=%v", err)
- flushLogAndExit(1)
- }
-
- var members []*model.TeamMember
- if result := <-api.Srv.Store.Team().GetMembers(team.Id); result.Err != nil {
- l4g.Error("Failed to load team membership details=%v", result.Err)
- flushLogAndExit(1)
- } else {
- members = result.Data.([]*model.TeamMember)
- }
-
- for _, user := range users {
- shouldUpdateUser := false
- shouldUpdateRole := false
- previousRole := user.Roles
- previousEmail := user.Email
- previousUsername := user.Username
-
- member := &model.TeamMember{
- TeamId: team.Id,
- UserId: user.Id,
- }
-
- if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) {
- member.Roles = model.ROLE_TEAM_ADMIN
- user.Roles = ""
- shouldUpdateRole = true
- }
-
- exists := false
- for _, member := range members {
- if member.UserId == user.Id {
- exists = true
- break
- }
- }
-
- if !exists {
- if result := <-api.Srv.Store.Team().SaveMember(member); result.Err != nil {
- l4g.Error("Failed to save membership for %v details=%v", user.Email, result.Err)
- flushLogAndExit(1)
- }
- }
-
- err := api.MoveFile(
- "teams/"+team.Id+"/users/"+user.Id+"/profile.png",
- "users/"+user.Id+"/profile.png",
- )
-
- if err != nil {
- l4g.Warn("No profile image to move for %v", user.Email)
- }
-
- if uniqueEmails[user.Email] {
- shouldUpdateUser = true
- emailParts := strings.Split(user.Email, "@")
- if len(emailParts) == 2 {
- user.Email = emailParts[0] + "+" + team.Name + "@" + emailParts[1]
- } else {
- user.Email = user.Email + "." + team.Name
- }
-
- if len(user.Email) > 127 {
- user.Email = user.Email[:127]
- }
- }
-
- if uniqueUsernames[user.Username] {
- shouldUpdateUser = true
- user.Username = team.Name + "." + user.Username
-
- if len(user.Username) > 63 {
- user.Username = user.Username[:63]
- }
- }
-
- if user.AuthData != nil && *user.AuthData != "" && uniqueAuths[*user.AuthData] {
- shouldUpdateUser = true
- }
-
- if shouldUpdateUser {
- if _, err := store.GetMaster().Exec(`
- UPDATE Users
- SET
- Email = :Email,
- Username = :Username,
- Roles = :Roles,
- AuthService = '',
- AuthData = NULL
- WHERE
- Id = :Id
- `,
- map[string]interface{}{
- "Email": user.Email,
- "Username": user.Username,
- "Roles": user.Roles,
- "Id": user.Id,
- },
- ); err != nil {
- l4g.Error("Failed to update user %v details=%v", user.Email, err)
- flushLogAndExit(1)
- }
-
- l4g.Info("modified user_id=%v, changed email from=%v to=%v, changed username from=%v to %v changed roles from=%v to=%v", user.Id, previousEmail, user.Email, previousUsername, user.Username, previousRole, user.Roles)
-
- emailChanged := previousEmail != user.Email
- usernameChanged := previousUsername != user.Username
-
- if emailChanged || usernameChanged {
- bodyPage := utils.NewHTMLTemplate("upgrade_30_body", "")
-
- EmailChanged := ""
- UsernameChanged := ""
-
- if emailChanged {
- EmailChanged = "true"
- }
-
- if usernameChanged {
- UsernameChanged = "true"
- }
-
- bodyPage.Html["Info"] = template.HTML(utils.T("api.templates.upgrade_30_body.info",
- map[string]interface{}{
- "SiteName": utils.ClientCfg["SiteName"],
- "TeamName": team.Name,
- "Email": user.Email,
- "Username": user.Username,
- "EmailChanged": EmailChanged,
- "UsernameChanged": UsernameChanged,
- }))
-
- utils.SendMail(
- previousEmail,
- utils.T("api.templates.upgrade_30_subject.info"),
- bodyPage.Render(),
- )
- }
- }
-
- if shouldUpdateRole {
- if _, err := store.GetMaster().Exec(`
- UPDATE Users
- SET
- Roles = ''
- WHERE
- Id = :Id
- `,
- map[string]interface{}{
- "Id": user.Id,
- },
- ); err != nil {
- l4g.Error("Failed to update user role %v details=%v", user.Email, err)
- flushLogAndExit(1)
- }
-
- l4g.Info("modified user_id=%v, changed roles from=%v to=%v", user.Id, previousRole, user.Roles)
- }
-
- uniqueEmails[user.Email] = true
- uniqueUsernames[user.Username] = true
-
- if user.AuthData != nil && *user.AuthData != "" {
- uniqueAuths[*user.AuthData] = true
- }
- }
-
- return users
-}
-
func cmdCreateTeam() {
if flagCmdCreateTeam {
if len(flagTeamName) == 0 {
diff --git a/store/sql_audit_store.go b/store/sql_audit_store.go
index 772a549a3..78e875a74 100644
--- a/store/sql_audit_store.go
+++ b/store/sql_audit_store.go
@@ -27,9 +27,6 @@ func NewSqlAuditStore(sqlStore *SqlStore) AuditStore {
return s
}
-func (s SqlAuditStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlAuditStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_audits_user_id", "Audits", "UserId")
}
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index 463bc0678..acf112f50 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -45,9 +45,6 @@ func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
return s
}
-func (s SqlChannelStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlChannelStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_channels_team_id", "Channels", "TeamId")
s.CreateIndexIfNotExists("idx_channels_name", "Channels", "Name")
diff --git a/store/sql_command_store.go b/store/sql_command_store.go
index 02b3a0cc5..4332f1e93 100644
--- a/store/sql_command_store.go
+++ b/store/sql_command_store.go
@@ -34,10 +34,6 @@ func NewSqlCommandStore(sqlStore *SqlStore) CommandStore {
return s
}
-func (s SqlCommandStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("Commands", "Description", "varchar(128)", "varchar(128)", "")
-}
-
func (s SqlCommandStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_command_team_id", "Commands", "TeamId")
}
diff --git a/store/sql_compliance_store.go b/store/sql_compliance_store.go
index 57872aef4..248d5c47b 100644
--- a/store/sql_compliance_store.go
+++ b/store/sql_compliance_store.go
@@ -30,9 +30,6 @@ func NewSqlComplianceStore(sqlStore *SqlStore) ComplianceStore {
return s
}
-func (s SqlComplianceStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlComplianceStore) CreateIndexesIfNotExists() {
}
diff --git a/store/sql_emoji_store.go b/store/sql_emoji_store.go
index 99434ee64..45af85931 100644
--- a/store/sql_emoji_store.go
+++ b/store/sql_emoji_store.go
@@ -26,9 +26,6 @@ func NewSqlEmojiStore(sqlStore *SqlStore) EmojiStore {
return s
}
-func (es SqlEmojiStore) UpgradeSchemaIfNeeded() {
-}
-
func (es SqlEmojiStore) CreateIndexesIfNotExists() {
}
diff --git a/store/sql_license_store.go b/store/sql_license_store.go
index f5d67bc5d..73faad8b9 100644
--- a/store/sql_license_store.go
+++ b/store/sql_license_store.go
@@ -23,9 +23,6 @@ func NewSqlLicenseStore(sqlStore *SqlStore) LicenseStore {
return ls
}
-func (ls SqlLicenseStore) UpgradeSchemaIfNeeded() {
-}
-
func (ls SqlLicenseStore) CreateIndexesIfNotExists() {
}
diff --git a/store/sql_oauth_store.go b/store/sql_oauth_store.go
index 0ee9f1ad1..4a15d4f80 100644
--- a/store/sql_oauth_store.go
+++ b/store/sql_oauth_store.go
@@ -47,20 +47,6 @@ func NewSqlOAuthStore(sqlStore *SqlStore) OAuthStore {
return as
}
-func (as SqlOAuthStore) UpgradeSchemaIfNeeded() {
- as.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0")
- as.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "")
- as.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "")
- as.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "")
- as.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0")
-
- // ADDED for 3.3 REMOVE for 3.7
- if as.DoesColumnExist("OAuthAccessData", "AuthCode") {
- as.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData")
- as.RemoveColumnIfExists("OAuthAccessData", "AuthCode")
- }
-}
-
func (as SqlOAuthStore) CreateIndexesIfNotExists() {
as.CreateIndexIfNotExists("idx_oauthapps_creator_id", "OAuthApps", "CreatorId")
as.CreateIndexIfNotExists("idx_oauthaccessdata_client_id", "OAuthAccessData", "ClientId")
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index b844bfbca..629308316 100644
--- a/store/sql_post_store.go
+++ b/store/sql_post_store.go
@@ -37,9 +37,6 @@ func NewSqlPostStore(sqlStore *SqlStore) PostStore {
return s
}
-func (s SqlPostStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlPostStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_posts_update_at", "Posts", "UpdateAt")
s.CreateIndexIfNotExists("idx_posts_create_at", "Posts", "CreateAt")
diff --git a/store/sql_preference_store.go b/store/sql_preference_store.go
index a701c3cb8..f6a3b64dc 100644
--- a/store/sql_preference_store.go
+++ b/store/sql_preference_store.go
@@ -32,9 +32,6 @@ func NewSqlPreferenceStore(sqlStore *SqlStore) PreferenceStore {
return s
}
-func (s SqlPreferenceStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlPreferenceStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_preferences_user_id", "Preferences", "UserId")
s.CreateIndexIfNotExists("idx_preferences_category", "Preferences", "Category")
diff --git a/store/sql_recovery_store.go b/store/sql_recovery_store.go
index 17a444ebb..80c86c67c 100644
--- a/store/sql_recovery_store.go
+++ b/store/sql_recovery_store.go
@@ -23,9 +23,6 @@ func NewSqlPasswordRecoveryStore(sqlStore *SqlStore) PasswordRecoveryStore {
return s
}
-func (s SqlPasswordRecoveryStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlPasswordRecoveryStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_password_recovery_code", "PasswordRecovery", "Code")
}
diff --git a/store/sql_session_store.go b/store/sql_session_store.go
index 94694267c..4ddc06302 100644
--- a/store/sql_session_store.go
+++ b/store/sql_session_store.go
@@ -29,14 +29,6 @@ func NewSqlSessionStore(sqlStore *SqlStore) SessionStore {
return us
}
-func (me SqlSessionStore) UpgradeSchemaIfNeeded() {
- // ADDED for 2.1 REMOVE for 2.5
- deviceIdLength := me.GetMaxLengthOfColumnIfExists("Sessions", "DeviceId")
- if len(deviceIdLength) > 0 && deviceIdLength != "512" {
- me.AlterColumnTypeIfExists("Sessions", "DeviceId", "VARCHAR(512)", "VARCHAR(512)")
- }
-}
-
func (me SqlSessionStore) CreateIndexesIfNotExists() {
me.CreateIndexIfNotExists("idx_sessions_user_id", "Sessions", "UserId")
me.CreateIndexIfNotExists("idx_sessions_token", "Sessions", "Token")
diff --git a/store/sql_status_store.go b/store/sql_status_store.go
index bb3c7c364..f5259c212 100644
--- a/store/sql_status_store.go
+++ b/store/sql_status_store.go
@@ -28,9 +28,6 @@ func NewSqlStatusStore(sqlStore *SqlStore) StatusStore {
return s
}
-func (s SqlStatusStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlStatusStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_status_user_id", "Status", "UserId")
s.CreateIndexIfNotExists("idx_status_status", "Status", "Status")
diff --git a/store/sql_store.go b/store/sql_store.go
index 2047ad150..4185bb705 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -35,6 +35,33 @@ const (
INDEX_TYPE_DEFAULT = "default"
)
+const (
+ EXIT_CREATE_TABLE = 100
+ EXIT_DB_OPEN = 101
+ EXIT_PING = 102
+ EXIT_NO_DRIVER = 103
+ EXIT_TABLE_EXISTS = 104
+ EXIT_TABLE_EXISTS_MYSQL = 105
+ EXIT_COLUMN_EXISTS = 106
+ EXIT_DOES_COLUMN_EXISTS_POSTGRES = 107
+ EXIT_DOES_COLUMN_EXISTS_MYSQL = 108
+ EXIT_DOES_COLUMN_EXISTS_MISSING = 109
+ EXIT_CREATE_COLUMN_POSTGRES = 110
+ EXIT_CREATE_COLUMN_MYSQL = 111
+ EXIT_CREATE_COLUMN_MISSING = 112
+ EXIT_REMOVE_COLUMN = 113
+ EXIT_RENAME_COLUMN = 114
+ EXIT_MAX_COLUMN = 115
+ EXIT_ALTER_COLUMN = 116
+ EXIT_CREATE_INDEX_POSTGRES = 117
+ EXIT_CREATE_INDEX_MYSQL = 118
+ EXIT_CREATE_INDEX_FULL_MYSQL = 119
+ EXIT_CREATE_INDEX_MISSING = 120
+ EXIT_REMOVE_INDEX_POSTGRES = 121
+ EXIT_REMOVE_INDEX_MYSQL = 122
+ EXIT_REMOVE_INDEX_MISSING = 123
+)
+
type SqlStore struct {
master *gorp.DbMap
replicas []*gorp.DbMap
@@ -86,35 +113,6 @@ func NewSqlStore() Store {
sqlStore := initConnection()
- // If the version is already set then we are potentially in an 'upgrade needed' state
- if sqlStore.SchemaVersion != "" {
- // Check to see if it's the most current database schema version
- if !model.IsCurrentVersion(sqlStore.SchemaVersion) {
- // If we are upgrading from the previous version then print a warning and continue
- if model.IsPreviousVersionsSupported(sqlStore.SchemaVersion) {
- l4g.Warn(utils.T("store.sql.schema_out_of_date.warn"), sqlStore.SchemaVersion)
- l4g.Warn(utils.T("store.sql.schema_upgrade_attempt.warn"), model.CurrentVersion)
- } else {
- // If this is an 'upgrade needed' state but the user is attempting to skip a version then halt the world
- l4g.Critical(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion)
- time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion))
- }
- }
- }
-
- // This is a special case for upgrading the schema to the 3.0 user model
- // ADDED for 3.0 REMOVE for 3.4
- if sqlStore.SchemaVersion == "2.2.0" ||
- sqlStore.SchemaVersion == "2.1.0" ||
- sqlStore.SchemaVersion == "2.0.0" {
- l4g.Critical("The database version of %v cannot be automatically upgraded to 3.0 schema", sqlStore.SchemaVersion)
- l4g.Critical("You will need to run the command line tool './platform -upgrade_db_30'")
- l4g.Critical("Please see 'http://www.mattermost.org/upgrade-to-3-0/' for more information on how to upgrade.")
- time.Sleep(time.Second)
- os.Exit(1)
- }
-
sqlStore.team = NewSqlTeamStore(sqlStore)
sqlStore.channel = NewSqlChannelStore(sqlStore)
sqlStore.post = NewSqlPostStore(sqlStore)
@@ -136,25 +134,10 @@ func NewSqlStore() Store {
if err != nil {
l4g.Critical(utils.T("store.sql.creating_tables.critical"), err)
time.Sleep(time.Second)
- os.Exit(1)
- }
-
- sqlStore.team.(*SqlTeamStore).UpgradeSchemaIfNeeded()
- sqlStore.channel.(*SqlChannelStore).UpgradeSchemaIfNeeded()
- sqlStore.post.(*SqlPostStore).UpgradeSchemaIfNeeded()
- sqlStore.user.(*SqlUserStore).UpgradeSchemaIfNeeded()
- sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded()
- sqlStore.compliance.(*SqlComplianceStore).UpgradeSchemaIfNeeded()
- sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
- sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded()
- sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded()
- sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded()
- sqlStore.command.(*SqlCommandStore).UpgradeSchemaIfNeeded()
- sqlStore.preference.(*SqlPreferenceStore).UpgradeSchemaIfNeeded()
- sqlStore.license.(*SqlLicenseStore).UpgradeSchemaIfNeeded()
- sqlStore.recovery.(*SqlPasswordRecoveryStore).UpgradeSchemaIfNeeded()
- sqlStore.emoji.(*SqlEmojiStore).UpgradeSchemaIfNeeded()
- sqlStore.status.(*SqlStatusStore).UpgradeSchemaIfNeeded()
+ os.Exit(EXIT_CREATE_TABLE)
+ }
+
+ UpgradeDatabase(sqlStore)
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
@@ -175,37 +158,6 @@ func NewSqlStore() Store {
sqlStore.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
- if model.IsPreviousVersionsSupported(sqlStore.SchemaVersion) && !model.IsCurrentVersion(sqlStore.SchemaVersion) {
- sqlStore.system.Update(&model.System{Name: "Version", Value: model.CurrentVersion})
- sqlStore.SchemaVersion = model.CurrentVersion
- l4g.Warn(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
- }
-
- if sqlStore.SchemaVersion == "" {
- sqlStore.system.Save(&model.System{Name: "Version", Value: model.CurrentVersion})
- sqlStore.SchemaVersion = model.CurrentVersion
- l4g.Info(utils.T("store.sql.schema_set.info"), model.CurrentVersion)
- }
-
- return sqlStore
-}
-
-// ADDED for 3.0 REMOVE for 3.4
-// This is a special case for upgrading the schema to the 3.0 user model
-func NewSqlStoreForUpgrade30() *SqlStore {
- sqlStore := initConnection()
-
- sqlStore.team = NewSqlTeamStore(sqlStore)
- sqlStore.user = NewSqlUserStore(sqlStore)
- sqlStore.system = NewSqlSystemStore(sqlStore)
-
- err := sqlStore.master.CreateTablesIfNotExists()
- if err != nil {
- l4g.Critical(utils.T("store.sql.creating_tables.critical"), err)
- time.Sleep(time.Second)
- os.Exit(1)
- }
-
return sqlStore
}
@@ -215,7 +167,7 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
if err != nil {
l4g.Critical(utils.T("store.sql.open_conn.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.open_conn.critical"), err.Error()))
+ os.Exit(EXIT_DB_OPEN)
}
l4g.Info(utils.T("store.sql.pinging.info"), con_type)
@@ -223,7 +175,7 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
if err != nil {
l4g.Critical(utils.T("store.sql.ping.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.open_conn.panic"), err.Error()))
+ os.Exit(EXIT_PING)
}
db.SetMaxIdleConns(maxIdle)
@@ -240,7 +192,7 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
} else {
l4g.Critical(utils.T("store.sql.dialect_driver.critical"))
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.dialect_driver.panic"), err.Error()))
+ os.Exit(EXIT_NO_DRIVER)
}
if trace {
@@ -276,7 +228,7 @@ func (ss SqlStore) DoesTableExist(tableName string) bool {
if err != nil {
l4g.Critical(utils.T("store.sql.table_exists.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.table_exists.critical"), err.Error()))
+ os.Exit(EXIT_TABLE_EXISTS)
}
return count > 0
@@ -298,7 +250,7 @@ func (ss SqlStore) DoesTableExist(tableName string) bool {
if err != nil {
l4g.Critical(utils.T("store.sql.table_exists.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.table_exists.critical"), err.Error()))
+ os.Exit(EXIT_TABLE_EXISTS_MYSQL)
}
return count > 0
@@ -306,9 +258,9 @@ func (ss SqlStore) DoesTableExist(tableName string) bool {
} else {
l4g.Critical(utils.T("store.sql.column_exists_missing_driver.critical"))
time.Sleep(time.Second)
- panic(utils.T("store.sql.column_exists_missing_driver.critical"))
+ os.Exit(EXIT_COLUMN_EXISTS)
+ return false
}
-
}
func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
@@ -330,7 +282,7 @@ func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
l4g.Critical(utils.T("store.sql.column_exists.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.column_exists.critical"), err.Error()))
+ os.Exit(EXIT_DOES_COLUMN_EXISTS_POSTGRES)
}
return count > 0
@@ -353,7 +305,7 @@ func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
if err != nil {
l4g.Critical(utils.T("store.sql.column_exists.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.column_exists.critical"), err.Error()))
+ os.Exit(EXIT_DOES_COLUMN_EXISTS_MYSQL)
}
return count > 0
@@ -361,9 +313,9 @@ func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
} else {
l4g.Critical(utils.T("store.sql.column_exists_missing_driver.critical"))
time.Sleep(time.Second)
- panic(utils.T("store.sql.column_exists_missing_driver.critical"))
+ os.Exit(EXIT_DOES_COLUMN_EXISTS_MISSING)
+ return false
}
-
}
func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool {
@@ -377,7 +329,7 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
if err != nil {
l4g.Critical(utils.T("store.sql.create_column.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.create_column.critical"), err.Error()))
+ os.Exit(EXIT_CREATE_COLUMN_POSTGRES)
}
return true
@@ -387,7 +339,7 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
if err != nil {
l4g.Critical(utils.T("store.sql.create_column.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.create_column.critical"), err.Error()))
+ os.Exit(EXIT_CREATE_COLUMN_MYSQL)
}
return true
@@ -395,7 +347,8 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
} else {
l4g.Critical(utils.T("store.sql.create_column_missing_driver.critical"))
time.Sleep(time.Second)
- panic(utils.T("store.sql.create_column_missing_driver.critical"))
+ os.Exit(EXIT_CREATE_COLUMN_MISSING)
+ return false
}
}
@@ -409,7 +362,7 @@ func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) boo
if err != nil {
l4g.Critical(utils.T("store.sql.drop_column.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.drop_column.critical"), err.Error()))
+ os.Exit(EXIT_REMOVE_COLUMN)
}
return true
@@ -430,7 +383,7 @@ func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string,
if err != nil {
l4g.Critical(utils.T("store.sql.rename_column.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.rename_column.critical"), err.Error()))
+ os.Exit(EXIT_RENAME_COLUMN)
}
return true
@@ -452,7 +405,7 @@ func (ss SqlStore) GetMaxLengthOfColumnIfExists(tableName string, columnName str
if err != nil {
l4g.Critical(utils.T("store.sql.maxlength_column.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.maxlength_column.critical"), err.Error()))
+ os.Exit(EXIT_MAX_COLUMN)
}
return result
@@ -473,7 +426,7 @@ func (ss SqlStore) AlterColumnTypeIfExists(tableName string, columnName string,
if err != nil {
l4g.Critical(utils.T("store.sql.alter_column_type.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.alter_column_type.critical"), err.Error()))
+ os.Exit(EXIT_ALTER_COLUMN)
}
return true
@@ -516,7 +469,7 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
if err != nil {
l4g.Critical(utils.T("store.sql.create_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.create_index.critical"), err.Error()))
+ os.Exit(EXIT_CREATE_INDEX_POSTGRES)
}
} else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
@@ -524,7 +477,7 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
if err != nil {
l4g.Critical(utils.T("store.sql.check_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.check_index.critical"), err.Error()))
+ os.Exit(EXIT_CREATE_INDEX_MYSQL)
}
if count > 0 {
@@ -540,12 +493,12 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
if err != nil {
l4g.Critical(utils.T("store.sql.create_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.create_index.critical"), err.Error()))
+ os.Exit(EXIT_CREATE_INDEX_FULL_MYSQL)
}
} else {
l4g.Critical(utils.T("store.sql.create_index_missing_driver.critical"))
time.Sleep(time.Second)
- panic(utils.T("store.sql.create_index_missing_driver.critical"))
+ os.Exit(EXIT_CREATE_INDEX_MISSING)
}
}
@@ -562,7 +515,7 @@ func (ss SqlStore) RemoveIndexIfExists(indexName string, tableName string) {
if err != nil {
l4g.Critical(utils.T("store.sql.remove_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.remove_index.critical"), err.Error()))
+ os.Exit(EXIT_REMOVE_INDEX_POSTGRES)
}
} else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
@@ -570,7 +523,7 @@ func (ss SqlStore) RemoveIndexIfExists(indexName string, tableName string) {
if err != nil {
l4g.Critical(utils.T("store.sql.check_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.check_index.critical"), err.Error()))
+ os.Exit(EXIT_REMOVE_INDEX_MYSQL)
}
if count > 0 {
@@ -581,12 +534,12 @@ func (ss SqlStore) RemoveIndexIfExists(indexName string, tableName string) {
if err != nil {
l4g.Critical(utils.T("store.sql.remove_index.critical"), err)
time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql.remove_index.critical"), err.Error()))
+ os.Exit(EXIT_REMOVE_INDEX_MYSQL)
}
} else {
l4g.Critical(utils.T("store.sql.create_index_missing_driver.critical"))
time.Sleep(time.Second)
- panic(utils.T("store.sql.create_index_missing_driver.critical"))
+ os.Exit(EXIT_REMOVE_INDEX_MISSING)
}
}
@@ -603,20 +556,6 @@ func IsUniqueConstraintError(err string, indexName []string) bool {
return unique && field
}
-// func (ss SqlStore) GetColumnDataType(tableName, columnName string) string {
-// dataType, err := ss.GetMaster().SelectStr("SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS where table_name = :Tablename AND column_name = :Columnname", map[string]interface{}{
-// "Tablename": tableName,
-// "Columnname": columnName,
-// })
-// if err != nil {
-// l4g.Critical(utils.T("store.sql.table_column_type.critical"), columnName, tableName, err.Error())
-// time.Sleep(time.Second)
-// panic(fmt.Sprintf(utils.T("store.sql.table_column_type.critical"), columnName, tableName, err.Error()))
-// }
-
-// return dataType
-// }
-
func (ss SqlStore) GetMaster() *gorp.DbMap {
return ss.master
}
diff --git a/store/sql_store_test.go b/store/sql_store_test.go
index 721e708b5..d65d591ad 100644
--- a/store/sql_store_test.go
+++ b/store/sql_store_test.go
@@ -34,34 +34,6 @@ func TestSqlStore1(t *testing.T) {
utils.LoadConfig("config.json")
}
-func TestSqlStore2(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Fatal("should have been fatal")
- }
- }()
-
- utils.LoadConfig("config.json")
- utils.Cfg.SqlSettings.DriverName = "missing"
- store = NewSqlStore()
-
- utils.LoadConfig("config.json")
-}
-
-func TestSqlStore3(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Fatal("should have been fatal")
- }
- }()
-
- utils.LoadConfig("config.json")
- utils.Cfg.SqlSettings.DataSource = "missing"
- store = NewSqlStore()
-
- utils.LoadConfig("config.json")
-}
-
func TestEncrypt(t *testing.T) {
m := make(map[string]string)
diff --git a/store/sql_system_store.go b/store/sql_system_store.go
index a2b4f6396..6ae350720 100644
--- a/store/sql_system_store.go
+++ b/store/sql_system_store.go
@@ -23,9 +23,6 @@ func NewSqlSystemStore(sqlStore *SqlStore) SystemStore {
return s
}
-func (s SqlSystemStore) UpgradeSchemaIfNeeded() {
-}
-
func (s SqlSystemStore) CreateIndexesIfNotExists() {
}
diff --git a/store/sql_team_store.go b/store/sql_team_store.go
index 002d2a3ea..0544ec76c 100644
--- a/store/sql_team_store.go
+++ b/store/sql_team_store.go
@@ -40,10 +40,6 @@ func NewSqlTeamStore(sqlStore *SqlStore) TeamStore {
return s
}
-func (s SqlTeamStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("TeamMembers", "DeleteAt", "bigint(20)", "bigint", "0")
-}
-
func (s SqlTeamStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name")
s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId")
diff --git a/store/sql_upgrade.go b/store/sql_upgrade.go
new file mode 100644
index 000000000..293d1ce6b
--- /dev/null
+++ b/store/sql_upgrade.go
@@ -0,0 +1,190 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package store
+
+import (
+ "os"
+ "strings"
+ "time"
+
+ l4g "github.com/alecthomas/log4go"
+
+ "github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
+)
+
+const (
+ VERSION_3_4_0 = "3.4.0"
+ VERSION_3_3_0 = "3.3.0"
+ VERSION_3_2_0 = "3.2.0"
+ VERSION_3_1_0 = "3.1.0"
+ VERSION_3_0_0 = "3.0.0"
+)
+
+const (
+ EXIT_VERSION_SAVE_MISSING = 1001
+ EXIT_TOO_OLD = 1002
+ EXIT_VERSION_SAVE = 1003
+ EXIT_THEME_MIGRATION = 1004
+)
+
+func UpgradeDatabase(sqlStore *SqlStore) {
+
+ UpgradeDatabaseToVersion31(sqlStore)
+ UpgradeDatabaseToVersion32(sqlStore)
+ UpgradeDatabaseToVersion33(sqlStore)
+ UpgradeDatabaseToVersion34(sqlStore)
+
+ // If the SchemaVersion is empty this this is the first time it has ran
+ // so lets set it to the current version.
+ if sqlStore.SchemaVersion == "" {
+ if result := <-sqlStore.system.Save(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
+ l4g.Critical(result.Err.Error())
+ time.Sleep(time.Second)
+ os.Exit(EXIT_VERSION_SAVE_MISSING)
+ }
+
+ sqlStore.SchemaVersion = model.CurrentVersion
+ l4g.Info(utils.T("store.sql.schema_set.info"), model.CurrentVersion)
+ }
+
+ // If we're not on the current version then it's too old to be upgraded
+ if sqlStore.SchemaVersion != model.CurrentVersion {
+ l4g.Critical(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion)
+ time.Sleep(time.Second)
+ os.Exit(EXIT_TOO_OLD)
+ }
+}
+
+func saveSchemaVersion(sqlStore *SqlStore, version string) {
+ if result := <-sqlStore.system.Update(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
+ l4g.Critical(result.Err.Error())
+ time.Sleep(time.Second)
+ os.Exit(EXIT_VERSION_SAVE)
+ }
+
+ sqlStore.SchemaVersion = version
+ l4g.Info(utils.T("store.sql.upgraded.warn"), version)
+}
+
+func shouldPerformUpgrade(sqlStore *SqlStore, currentSchemaVersion string, expectedSchemaVersion string) bool {
+ if sqlStore.SchemaVersion == currentSchemaVersion {
+ l4g.Info(utils.T("store.sql.schema_out_of_date.warn"), currentSchemaVersion)
+ l4g.Info(utils.T("store.sql.schema_upgrade_attempt.warn"), expectedSchemaVersion)
+
+ return true
+ }
+
+ return false
+}
+
+func UpgradeDatabaseToVersion31(sqlStore *SqlStore) {
+ if shouldPerformUpgrade(sqlStore, VERSION_3_0_0, VERSION_3_1_0) {
+ sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "")
+ saveSchemaVersion(sqlStore, VERSION_3_1_0)
+ }
+}
+
+func UpgradeDatabaseToVersion32(sqlStore *SqlStore) {
+ if shouldPerformUpgrade(sqlStore, VERSION_3_1_0, VERSION_3_2_0) {
+ sqlStore.CreateColumnIfNotExists("TeamMembers", "DeleteAt", "bigint(20)", "bigint", "0")
+
+ if sqlStore.DoesColumnExist("Users", "ThemeProps") {
+ params := map[string]interface{}{
+ "Category": model.PREFERENCE_CATEGORY_THEME,
+ "Name": "",
+ }
+
+ transaction, err := sqlStore.GetMaster().Begin()
+ if err != nil {
+ themeMigrationFailed(err)
+ }
+
+ // increase size of Value column of Preferences table to match the size of the ThemeProps column
+ if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
+ if _, err := transaction.Exec("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil {
+ themeMigrationFailed(err)
+ }
+ } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
+ if _, err := transaction.Exec("ALTER TABLE Preferences MODIFY Value text"); err != nil {
+ themeMigrationFailed(err)
+ }
+ }
+
+ // copy data across
+ if _, err := transaction.Exec(
+ `INSERT INTO
+ Preferences(UserId, Category, Name, Value)
+ SELECT
+ Id, '`+model.PREFERENCE_CATEGORY_THEME+`', '', ThemeProps
+ FROM
+ Users
+ WHERE
+ Users.ThemeProps != 'null'`, params); err != nil {
+ themeMigrationFailed(err)
+ }
+
+ // delete old data
+ if _, err := transaction.Exec("ALTER TABLE Users DROP COLUMN ThemeProps"); err != nil {
+ themeMigrationFailed(err)
+ }
+
+ if err := transaction.Commit(); err != nil {
+ themeMigrationFailed(err)
+ }
+
+ // rename solarized_* code themes to solarized-* to match client changes in 3.0
+ var data model.Preferences
+ if _, err := sqlStore.GetMaster().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PREFERENCE_CATEGORY_THEME+"' AND Value LIKE '%solarized_%'"); err == nil {
+ for i := range data {
+ data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1)
+ }
+
+ sqlStore.Preference().Save(&data)
+ }
+ }
+
+ saveSchemaVersion(sqlStore, VERSION_3_2_0)
+ }
+}
+
+func themeMigrationFailed(err error) {
+ l4g.Critical(utils.T("store.sql_user.migrate_theme.critical"), err)
+ time.Sleep(time.Second)
+ os.Exit(EXIT_THEME_MIGRATION)
+}
+
+func UpgradeDatabaseToVersion33(sqlStore *SqlStore) {
+ if shouldPerformUpgrade(sqlStore, VERSION_3_2_0, VERSION_3_3_0) {
+
+ sqlStore.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0")
+ sqlStore.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "")
+ sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "")
+ sqlStore.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "")
+ sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0")
+
+ if sqlStore.DoesColumnExist("OAuthAccessData", "AuthCode") {
+ sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData")
+ sqlStore.RemoveColumnIfExists("OAuthAccessData", "AuthCode")
+ }
+
+ sqlStore.RemoveColumnIfExists("Users", "LastActivityAt")
+ sqlStore.RemoveColumnIfExists("Users", "LastPingAt")
+
+ sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0")
+
+ saveSchemaVersion(sqlStore, VERSION_3_3_0)
+ }
+}
+
+func UpgradeDatabaseToVersion34(sqlStore *SqlStore) {
+ // TODO XXX FIXME should be removed before release
+ //if shouldPerformUpgrade(sqlStore, VERSION_3_3_0, VERSION_3_4_0) {
+
+ // do the actual upgrade
+
+ // TODO XXX FIXME should be removed before release
+ //saveSchemaVersion(sqlStore, VERSION_3_4_0)
+ //}
+}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index e26183c1e..027dcbd75 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -9,9 +9,7 @@ import (
"fmt"
"strconv"
"strings"
- "time"
- l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -49,77 +47,6 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
return us
}
-func (us SqlUserStore) UpgradeSchemaIfNeeded() {
- // ADDED for 2.0 REMOVE for 2.4
- us.CreateColumnIfNotExists("Users", "Locale", "varchar(5)", "character varying(5)", model.DEFAULT_LOCALE)
-
- // ADDED for 3.2 REMOVE for 3.6
- if us.DoesColumnExist("Users", "ThemeProps") {
- params := map[string]interface{}{
- "Category": model.PREFERENCE_CATEGORY_THEME,
- "Name": "",
- }
-
- transaction, err := us.GetMaster().Begin()
- if err != nil {
- themeMigrationFailed(err)
- }
-
- // increase size of Value column of Preferences table to match the size of the ThemeProps column
- if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
- if _, err := transaction.Exec("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil {
- themeMigrationFailed(err)
- }
- } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
- if _, err := transaction.Exec("ALTER TABLE Preferences MODIFY Value text"); err != nil {
- themeMigrationFailed(err)
- }
- }
-
- // copy data across
- if _, err := transaction.Exec(
- `INSERT INTO
- Preferences(UserId, Category, Name, Value)
- SELECT
- Id, '`+model.PREFERENCE_CATEGORY_THEME+`', '', ThemeProps
- FROM
- Users
- WHERE
- Users.ThemeProps != 'null'`, params); err != nil {
- themeMigrationFailed(err)
- }
-
- // delete old data
- if _, err := transaction.Exec("ALTER TABLE Users DROP COLUMN ThemeProps"); err != nil {
- themeMigrationFailed(err)
- }
-
- if err := transaction.Commit(); err != nil {
- themeMigrationFailed(err)
- }
-
- // rename solarized_* code themes to solarized-* to match client changes in 3.0
- var data model.Preferences
- if _, err := us.GetReplica().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PREFERENCE_CATEGORY_THEME+"' AND Value LIKE '%solarized_%'"); err == nil {
- for i := range data {
- data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1)
- }
-
- us.Preference().Save(&data)
- }
- }
-
- // ADDED for 3.3 remove for 3.7
- us.RemoveColumnIfExists("Users", "LastActivityAt")
- us.RemoveColumnIfExists("Users", "LastPingAt")
-}
-
-func themeMigrationFailed(err error) {
- l4g.Critical(utils.T("store.sql_user.migrate_theme.critical"), err)
- time.Sleep(time.Second)
- panic(fmt.Sprintf(utils.T("store.sql_user.migrate_theme.critical"), err.Error()))
-}
-
func (us SqlUserStore) CreateIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_users_email", "Users", "Email")
}
diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go
index 08b8f9976..a71ac6a88 100644
--- a/store/sql_webhook_store.go
+++ b/store/sql_webhook_store.go
@@ -40,16 +40,6 @@ func NewSqlWebhookStore(sqlStore *SqlStore) WebhookStore {
return s
}
-func (s SqlWebhookStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("IncomingWebhooks", "DisplayName", "varchar(64)", "varchar(64)", "")
- s.CreateColumnIfNotExists("IncomingWebhooks", "Description", "varchar(128)", "varchar(128)", "")
-
- s.CreateColumnIfNotExists("OutgoingWebhooks", "DisplayName", "varchar(64)", "varchar(64)", "")
- s.CreateColumnIfNotExists("OutgoingWebhooks", "Description", "varchar(128)", "varchar(128)", "")
- s.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "")
- s.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0")
-}
-
func (s SqlWebhookStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_incoming_webhook_user_id", "IncomingWebhooks", "UserId")
s.CreateIndexIfNotExists("idx_incoming_webhook_team_id", "IncomingWebhooks", "TeamId")