summaryrefslogtreecommitdiffstats
path: root/store/sql_store.go
diff options
context:
space:
mode:
Diffstat (limited to 'store/sql_store.go')
-rw-r--r--store/sql_store.go172
1 files changed, 144 insertions, 28 deletions
diff --git a/store/sql_store.go b/store/sql_store.go
index 98c67d668..6dcf2e8cd 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -38,6 +38,9 @@ type SqlStore struct {
user UserStore
audit AuditStore
session SessionStore
+ oauth OAuthStore
+ system SystemStore
+ webhook WebhookStore
}
func NewSqlStore() Store {
@@ -48,11 +51,44 @@ func NewSqlStore() Store {
utils.Cfg.SqlSettings.DataSource, utils.Cfg.SqlSettings.MaxIdleConns,
utils.Cfg.SqlSettings.MaxOpenConns, utils.Cfg.SqlSettings.Trace)
- sqlStore.replicas = make([]*gorp.DbMap, len(utils.Cfg.SqlSettings.DataSourceReplicas))
- for i, replica := range utils.Cfg.SqlSettings.DataSourceReplicas {
- sqlStore.replicas[i] = setupConnection(fmt.Sprintf("replica-%v", i), utils.Cfg.SqlSettings.DriverName, replica,
+ if len(utils.Cfg.SqlSettings.DataSourceReplicas) == 0 {
+ sqlStore.replicas = make([]*gorp.DbMap, 1)
+ sqlStore.replicas[0] = setupConnection(fmt.Sprintf("replica-%v", 0), utils.Cfg.SqlSettings.DriverName, utils.Cfg.SqlSettings.DataSource,
utils.Cfg.SqlSettings.MaxIdleConns, utils.Cfg.SqlSettings.MaxOpenConns,
utils.Cfg.SqlSettings.Trace)
+ } else {
+ sqlStore.replicas = make([]*gorp.DbMap, len(utils.Cfg.SqlSettings.DataSourceReplicas))
+ for i, replica := range utils.Cfg.SqlSettings.DataSourceReplicas {
+ sqlStore.replicas[i] = setupConnection(fmt.Sprintf("replica-%v", i), utils.Cfg.SqlSettings.DriverName, replica,
+ utils.Cfg.SqlSettings.MaxIdleConns, utils.Cfg.SqlSettings.MaxOpenConns,
+ 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.DoesTableExist("Sessions") {
+ if sqlStore.DoesColumnExist("Sessions", "AltId") {
+ sqlStore.GetMaster().Exec("DROP TABLE IF EXISTS Sessions")
+ }
}
sqlStore.team = NewSqlTeamStore(sqlStore)
@@ -61,22 +97,41 @@ func NewSqlStore() Store {
sqlStore.user = NewSqlUserStore(sqlStore)
sqlStore.audit = NewSqlAuditStore(sqlStore)
sqlStore.session = NewSqlSessionStore(sqlStore)
+ sqlStore.oauth = NewSqlOAuthStore(sqlStore)
+ sqlStore.system = NewSqlSystemStore(sqlStore)
+ sqlStore.webhook = NewSqlWebhookStore(sqlStore)
sqlStore.master.CreateTablesIfNotExists()
+ sqlStore.team.(*SqlTeamStore).UpgradeSchemaIfNeeded()
+ sqlStore.channel.(*SqlChannelStore).UpgradeSchemaIfNeeded()
+ sqlStore.post.(*SqlPostStore).UpgradeSchemaIfNeeded()
+ sqlStore.user.(*SqlUserStore).UpgradeSchemaIfNeeded()
+ sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded()
+ sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
+ sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded()
+ sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded()
+ sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded()
+
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
sqlStore.post.(*SqlPostStore).CreateIndexesIfNotExists()
sqlStore.user.(*SqlUserStore).CreateIndexesIfNotExists()
sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists()
+ sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists()
+ sqlStore.system.(*SqlSystemStore).CreateIndexesIfNotExists()
+ sqlStore.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
- sqlStore.team.(*SqlTeamStore).UpgradeSchemaIfNeeded()
- sqlStore.channel.(*SqlChannelStore).UpgradeSchemaIfNeeded()
- sqlStore.post.(*SqlPostStore).UpgradeSchemaIfNeeded()
- sqlStore.user.(*SqlUserStore).UpgradeSchemaIfNeeded()
- sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded()
- sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
+ 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
}
@@ -85,12 +140,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)
@@ -122,6 +177,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(
@@ -135,6 +240,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())
@@ -206,26 +315,21 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
}
}
-// func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
+func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
-// // XXX TODO FIXME this should be removed after 0.6.0
-// if utils.Cfg.SqlSettings.DriverName == "postgres" {
-// return false
-// }
-
-// if !ss.DoesColumnExist(tableName, columnName) {
-// return false
-// }
+ if !ss.DoesColumnExist(tableName, columnName) {
+ return false
+ }
-// _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
-// if err != nil {
-// l4g.Critical("Failed to drop column %v", err)
-// time.Sleep(time.Second)
-// panic("Failed to drop column " + err.Error())
-// }
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
+ if err != nil {
+ l4g.Critical("Failed to drop column %v", err)
+ time.Sleep(time.Second)
+ panic("Failed to drop column " + err.Error())
+ }
-// return true
-// }
+ return true
+}
// func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool {
@@ -363,6 +467,18 @@ func (ss SqlStore) Audit() AuditStore {
return ss.audit
}
+func (ss SqlStore) OAuth() OAuthStore {
+ return ss.oauth
+}
+
+func (ss SqlStore) System() SystemStore {
+ return ss.system
+}
+
+func (ss SqlStore) Webhook() WebhookStore {
+ return ss.webhook
+}
+
type mattermConverter struct{}
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {