summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-09-16 19:59:57 -0700
committer=Corey Hulen <corey@hulen.com>2015-09-16 19:59:57 -0700
commitabda39b6523f2563d4663036f13ad1c24dac161e (patch)
tree3573d568f220c8e778f872c0fb501a280bb87468
parent1e7f7852ad09d97c8d33012192bd1ff418881b8f (diff)
downloadchat-abda39b6523f2563d4663036f13ad1c24dac161e.tar.gz
chat-abda39b6523f2563d4663036f13ad1c24dac161e.tar.bz2
chat-abda39b6523f2563d4663036f13ad1c24dac161e.zip
Adding database schema version
-rw-r--r--model/system.go34
-rw-r--r--model/system_test.go19
-rw-r--r--store/sql_channel_store.go1
-rw-r--r--store/sql_store.go39
-rw-r--r--store/sql_system_store.go92
-rw-r--r--store/sql_system_store_test.go33
-rw-r--r--store/store.go7
7 files changed, 222 insertions, 3 deletions
diff --git a/model/system.go b/model/system.go
new file mode 100644
index 000000000..c79391cca
--- /dev/null
+++ b/model/system.go
@@ -0,0 +1,34 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+)
+
+type System struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+}
+
+func (o *System) ToJson() string {
+ b, err := json.Marshal(o)
+ if err != nil {
+ return ""
+ } else {
+ return string(b)
+ }
+}
+
+func SystemFromJson(data io.Reader) *System {
+ decoder := json.NewDecoder(data)
+ var o System
+ err := decoder.Decode(&o)
+ if err == nil {
+ return &o
+ } else {
+ return nil
+ }
+}
diff --git a/model/system_test.go b/model/system_test.go
new file mode 100644
index 000000000..14ba0db2e
--- /dev/null
+++ b/model/system_test.go
@@ -0,0 +1,19 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestSystemJson(t *testing.T) {
+ system := System{Name: "test", Value: NewId()}
+ json := system.ToJson()
+ result := SystemFromJson(strings.NewReader(json))
+
+ if result.Name != "test" {
+ t.Fatal("Ids do not match")
+ }
+}
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index b58166fd6..bc887df87 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -37,7 +37,6 @@ func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
}
func (s SqlChannelStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("Channels", "CreatorId", "varchar(26)", "character varying(26)", "")
}
func (s SqlChannelStore) CreateIndexesIfNotExists() {
diff --git a/store/sql_store.go b/store/sql_store.go
index 6ba73a0e5..1ae722f16 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,7 +57,24 @@ func NewSqlStore() Store {
utils.Cfg.SqlSettings.Trace)
}
- //version := sqlStore.GetCurrentSchemaVersion()
+ 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.IsLastVersion(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.GetFullVersion())
+ } 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") {
@@ -70,6 +88,7 @@ func NewSqlStore() Store {
sqlStore.audit = NewSqlAuditStore(sqlStore)
sqlStore.session = NewSqlSessionStore(sqlStore)
sqlStore.oauth = NewSqlOAuthStore(sqlStore)
+ sqlStore.system = NewSqlSystemStore(sqlStore)
sqlStore.master.CreateTablesIfNotExists()
@@ -80,6 +99,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()
@@ -88,6 +108,17 @@ func NewSqlStore() Store {
sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists()
sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists()
+ sqlStore.system.(*SqlSystemStore).CreateIndexesIfNotExists()
+
+ if model.IsLastVersion(schemaVersion) {
+ sqlStore.system.Update(&model.System{Name: "Version", Value: model.GetFullVersion()})
+ l4g.Warn("The database schema has been upgraded to version " + model.GetFullVersion())
+ }
+
+ if schemaVersion == "" {
+ sqlStore.system.Save(&model.System{Name: "Version", Value: model.GetFullVersion()})
+ l4g.Info("The database schema has been set to version " + model.GetFullVersion())
+ }
return sqlStore
}
@@ -134,7 +165,7 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
}
func (ss SqlStore) GetCurrentSchemaVersion() string {
- version, _ := ss.GetMaster().SelectStr("SELECT PropVal FROM MattermostSystem WHERE PropName='SchemaVersion'")
+ version, _ := ss.GetMaster().SelectStr("SELECT Value FROM Systems WHERE Name='Version'")
return version
}
@@ -383,6 +414,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) {
diff --git a/store/sql_system_store.go b/store/sql_system_store.go
new file mode 100644
index 000000000..ca22de2a6
--- /dev/null
+++ b/store/sql_system_store.go
@@ -0,0 +1,92 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package store
+
+import (
+ "github.com/mattermost/platform/model"
+)
+
+type SqlSystemStore struct {
+ *SqlStore
+}
+
+func NewSqlSystemStore(sqlStore *SqlStore) SystemStore {
+ s := &SqlSystemStore{sqlStore}
+
+ for _, db := range sqlStore.GetAllConns() {
+ table := db.AddTableWithName(model.System{}, "Systems").SetKeys(false, "Name")
+ table.ColMap("Name").SetMaxSize(64)
+ table.ColMap("Value").SetMaxSize(1024)
+ }
+
+ return s
+}
+
+func (s SqlSystemStore) UpgradeSchemaIfNeeded() {
+}
+
+func (s SqlSystemStore) CreateIndexesIfNotExists() {
+}
+
+func (s SqlSystemStore) Save(system *model.System) StoreChannel {
+
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ if err := s.GetMaster().Insert(system); err != nil {
+ result.Err = model.NewAppError("SqlSystemStore.Save", "We encounted an error saving the system property", "")
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlSystemStore) Update(system *model.System) StoreChannel {
+
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ if _, err := s.GetMaster().Update(system); err != nil {
+ result.Err = model.NewAppError("SqlSystemStore.Save", "We encounted an error updating the system property", "")
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlSystemStore) Get() StoreChannel {
+
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ var systems []model.System
+ props := make(model.StringMap)
+ if _, err := s.GetReplica().Select(&systems, "SELECT * FROM Systems"); err != nil {
+ result.Err = model.NewAppError("SqlSystemStore.Get", "We encounted an error finding the system properties", "")
+ } else {
+ for _, prop := range systems {
+ props[prop.Name] = prop.Value
+ }
+
+ result.Data = props
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
diff --git a/store/sql_system_store_test.go b/store/sql_system_store_test.go
new file mode 100644
index 000000000..0f03b8f0e
--- /dev/null
+++ b/store/sql_system_store_test.go
@@ -0,0 +1,33 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package store
+
+import (
+ "github.com/mattermost/platform/model"
+ "testing"
+)
+
+func TestSqlSystemStore(t *testing.T) {
+ Setup()
+
+ system := &model.System{Name: model.NewId(), Value: "value"}
+ Must(store.System().Save(system))
+
+ result := <-store.System().Get()
+ systems := result.Data.(model.StringMap)
+
+ if systems[system.Name] != system.Value {
+ t.Fatal()
+ }
+
+ system.Value = "value2"
+ Must(store.System().Update(system))
+
+ result2 := <-store.System().Get()
+ systems2 := result2.Data.(model.StringMap)
+
+ if systems2[system.Name] != system.Value {
+ t.Fatal()
+ }
+}
diff --git a/store/store.go b/store/store.go
index 0218bc757..1344c4ebe 100644
--- a/store/store.go
+++ b/store/store.go
@@ -35,6 +35,7 @@ type Store interface {
Audit() AuditStore
Session() SessionStore
OAuth() OAuthStore
+ System() SystemStore
Close()
}
@@ -130,3 +131,9 @@ type OAuthStore interface {
GetAccessDataByAuthCode(authCode string) StoreChannel
RemoveAccessData(token string) StoreChannel
}
+
+type SystemStore interface {
+ Save(system *model.System) StoreChannel
+ Update(system *model.System) StoreChannel
+ Get() StoreChannel
+}