Adding database schema version
Этот коммит содержится в:
34
model/system.go
Обычный файл
34
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
|
||||||
|
}
|
||||||
|
}
|
||||||
19
model/system_test.go
Обычный файл
19
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,6 @@ func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) UpgradeSchemaIfNeeded() {
|
func (s SqlChannelStore) UpgradeSchemaIfNeeded() {
|
||||||
s.CreateColumnIfNotExists("Channels", "CreatorId", "varchar(26)", "character varying(26)", "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) CreateIndexesIfNotExists() {
|
func (s SqlChannelStore) CreateIndexesIfNotExists() {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ type SqlStore struct {
|
|||||||
audit AuditStore
|
audit AuditStore
|
||||||
session SessionStore
|
session SessionStore
|
||||||
oauth OAuthStore
|
oauth OAuthStore
|
||||||
|
system SystemStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqlStore() Store {
|
func NewSqlStore() Store {
|
||||||
@@ -56,7 +57,24 @@ func NewSqlStore() Store {
|
|||||||
utils.Cfg.SqlSettings.Trace)
|
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
|
// Temporary upgrade code, remove after 0.8.0 release
|
||||||
if sqlStore.DoesColumnExist("Sessions", "AltId") {
|
if sqlStore.DoesColumnExist("Sessions", "AltId") {
|
||||||
@@ -70,6 +88,7 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.audit = NewSqlAuditStore(sqlStore)
|
sqlStore.audit = NewSqlAuditStore(sqlStore)
|
||||||
sqlStore.session = NewSqlSessionStore(sqlStore)
|
sqlStore.session = NewSqlSessionStore(sqlStore)
|
||||||
sqlStore.oauth = NewSqlOAuthStore(sqlStore)
|
sqlStore.oauth = NewSqlOAuthStore(sqlStore)
|
||||||
|
sqlStore.system = NewSqlSystemStore(sqlStore)
|
||||||
|
|
||||||
sqlStore.master.CreateTablesIfNotExists()
|
sqlStore.master.CreateTablesIfNotExists()
|
||||||
|
|
||||||
@@ -80,6 +99,7 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded()
|
sqlStore.audit.(*SqlAuditStore).UpgradeSchemaIfNeeded()
|
||||||
sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
|
sqlStore.session.(*SqlSessionStore).UpgradeSchemaIfNeeded()
|
||||||
sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded()
|
sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded()
|
||||||
|
sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded()
|
||||||
|
|
||||||
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
||||||
@@ -88,6 +108,17 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
|
sqlStore.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists()
|
sqlStore.session.(*SqlSessionStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.oauth.(*SqlOAuthStore).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
|
return sqlStore
|
||||||
}
|
}
|
||||||
@@ -134,7 +165,7 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ss SqlStore) GetCurrentSchemaVersion() string {
|
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
|
return version
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +414,10 @@ func (ss SqlStore) OAuth() OAuthStore {
|
|||||||
return ss.oauth
|
return ss.oauth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss SqlStore) System() SystemStore {
|
||||||
|
return ss.system
|
||||||
|
}
|
||||||
|
|
||||||
type mattermConverter struct{}
|
type mattermConverter struct{}
|
||||||
|
|
||||||
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {
|
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {
|
||||||
|
|||||||
92
store/sql_system_store.go
Обычный файл
92
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
|
||||||
|
}
|
||||||
33
store/sql_system_store_test.go
Обычный файл
33
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ type Store interface {
|
|||||||
Audit() AuditStore
|
Audit() AuditStore
|
||||||
Session() SessionStore
|
Session() SessionStore
|
||||||
OAuth() OAuthStore
|
OAuth() OAuthStore
|
||||||
|
System() SystemStore
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,3 +131,9 @@ type OAuthStore interface {
|
|||||||
GetAccessDataByAuthCode(authCode string) StoreChannel
|
GetAccessDataByAuthCode(authCode string) StoreChannel
|
||||||
RemoveAccessData(token string) StoreChannel
|
RemoveAccessData(token string) StoreChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SystemStore interface {
|
||||||
|
Save(system *model.System) StoreChannel
|
||||||
|
Update(system *model.System) StoreChannel
|
||||||
|
Get() StoreChannel
|
||||||
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user