diff options
Diffstat (limited to 'store/sql_store.go')
-rw-r--r-- | store/sql_store.go | 101 |
1 files changed, 97 insertions, 4 deletions
diff --git a/store/sql_store.go b/store/sql_store.go index c0b3c2021..adac47b4d 100644 --- a/store/sql_store.go +++ b/store/sql_store.go @@ -39,6 +39,7 @@ type SqlStore struct { audit AuditStore session SessionStore oauth OAuthStore + system SystemStore } func NewSqlStore() Store { @@ -56,9 +57,30 @@ func NewSqlStore() Store { utils.Cfg.SqlSettings.Trace) } + schemaVersion := sqlStore.GetCurrentSchemaVersion() + + // If the version is already set then we are potentially in an 'upgrade needed' state + if schemaVersion != "" { + // Check to see if it's the most current database schema version + if !model.IsCurrentVersion(schemaVersion) { + // If we are upgrading from the previous version then print a warning and continue + if model.IsPreviousVersion(schemaVersion) { + l4g.Warn("The database schema version of " + schemaVersion + " appears to be out of date") + l4g.Warn("Attempting to upgrade the database schema version to " + 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("The database schema version of " + schemaVersion + " cannot be upgraded. You must not skip a version.") + time.Sleep(time.Second) + panic("The database schema version of " + schemaVersion + " cannot be upgraded. You must not skip a version.") + } + } + } + // Temporary upgrade code, remove after 0.8.0 release - if sqlStore.DoesColumnExist("Sessions", "AltId") { - sqlStore.GetMaster().Exec("DROP TABLE IF EXISTS Sessions") + if sqlStore.DoesTableExist("Sessions") { + if sqlStore.DoesColumnExist("Sessions", "AltId") { + sqlStore.GetMaster().Exec("DROP TABLE IF EXISTS Sessions") + } } sqlStore.team = NewSqlTeamStore(sqlStore) @@ -68,6 +90,7 @@ func NewSqlStore() Store { sqlStore.audit = NewSqlAuditStore(sqlStore) sqlStore.session = NewSqlSessionStore(sqlStore) sqlStore.oauth = NewSqlOAuthStore(sqlStore) + sqlStore.system = NewSqlSystemStore(sqlStore) sqlStore.master.CreateTablesIfNotExists() @@ -78,6 +101,7 @@ func NewSqlStore() Store { sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded() sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded() sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded() + sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded() sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists() sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists() @@ -86,6 +110,17 @@ func NewSqlStore() Store { sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists() sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists() sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists() + sqlStore.system.(*SqlSystemStore).CreateIndexesIfNotExists() + + if model.IsPreviousVersion(schemaVersion) { + sqlStore.system.Update(&model.System{Name: "Version", Value: model.CurrentVersion}) + l4g.Warn("The database schema has been upgraded to version " + model.CurrentVersion) + } + + if schemaVersion == "" { + sqlStore.system.Save(&model.System{Name: "Version", Value: model.CurrentVersion}) + l4g.Info("The database schema has been set to version " + model.CurrentVersion) + } return sqlStore } @@ -94,12 +129,12 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle db, err := dbsql.Open(driver, dataSource) if err != nil { - l4g.Critical("Failed to open sql connection to '%v' err:%v", dataSource, err) + l4g.Critical("Failed to open sql connection to err:%v", err) time.Sleep(time.Second) panic("Failed to open sql connection" + err.Error()) } - l4g.Info("Pinging sql %v database at '%v'", con_type, dataSource) + l4g.Info("Pinging sql %v database", con_type) err = db.Ping() if err != nil { l4g.Critical("Failed to ping db err:%v", err) @@ -131,6 +166,56 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle return dbmap } +func (ss SqlStore) GetCurrentSchemaVersion() string { + version, _ := ss.GetMaster().SelectStr("SELECT Value FROM Systems WHERE Name='Version'") + return version +} + +func (ss SqlStore) DoesTableExist(tableName string) bool { + if utils.Cfg.SqlSettings.DriverName == "postgres" { + count, err := ss.GetMaster().SelectInt( + `SELECT count(relname) FROM pg_class WHERE relname=$1`, + strings.ToLower(tableName), + ) + + if err != nil { + l4g.Critical("Failed to check if table exists %v", err) + time.Sleep(time.Second) + panic("Failed to check if table exists " + err.Error()) + } + + return count > 0 + + } else if utils.Cfg.SqlSettings.DriverName == "mysql" { + + count, err := ss.GetMaster().SelectInt( + `SELECT + COUNT(0) AS table_exists + FROM + information_schema.TABLES + WHERE + TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = ? + `, + tableName, + ) + + if err != nil { + l4g.Critical("Failed to check if table exists %v", err) + time.Sleep(time.Second) + panic("Failed to check if table exists " + err.Error()) + } + + return count > 0 + + } else { + l4g.Critical("Failed to check if column exists because of missing driver") + time.Sleep(time.Second) + panic("Failed to check if column exists because of missing driver") + } + +} + func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool { if utils.Cfg.SqlSettings.DriverName == "postgres" { count, err := ss.GetMaster().SelectInt( @@ -144,6 +229,10 @@ func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool { ) if err != nil { + if err.Error() == "pq: relation \""+strings.ToLower(tableName)+"\" does not exist" { + return false + } + l4g.Critical("Failed to check if column exists %v", err) time.Sleep(time.Second) panic("Failed to check if column exists " + err.Error()) @@ -376,6 +465,10 @@ func (ss SqlStore) OAuth() OAuthStore { return ss.oauth } +func (ss SqlStore) System() SystemStore { + return ss.system +} + type mattermConverter struct{} func (me mattermConverter) ToDb(val interface{}) (interface{}, error) { |