From abda39b6523f2563d4663036f13ad1c24dac161e Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Wed, 16 Sep 2015 19:59:57 -0700 Subject: Adding database schema version --- store/sql_channel_store.go | 1 - store/sql_store.go | 39 +++++++++++++++++- store/sql_system_store.go | 92 ++++++++++++++++++++++++++++++++++++++++++ store/sql_system_store_test.go | 33 +++++++++++++++ store/store.go | 7 ++++ 5 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 store/sql_system_store.go create mode 100644 store/sql_system_store_test.go (limited to 'store') 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 +} -- cgit v1.2.3-1-g7c22