summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
Diffstat (limited to 'store')
-rw-r--r--store/redis.go75
-rw-r--r--store/redis_test.go59
-rw-r--r--store/sql_channel_store.go8
-rw-r--r--store/sql_channel_store_test.go4
-rw-r--r--store/sql_store.go47
-rw-r--r--store/sql_user_store.go27
6 files changed, 56 insertions, 164 deletions
diff --git a/store/redis.go b/store/redis.go
deleted file mode 100644
index 262040d43..000000000
--- a/store/redis.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package store
-
-import (
- l4g "code.google.com/p/log4go"
- "github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "gopkg.in/redis.v2"
- "strings"
- "time"
-)
-
-var client *redis.Client
-
-func RedisClient() *redis.Client {
-
- if client == nil {
-
- addr := utils.Cfg.RedisSettings.DataSource
-
- client = redis.NewTCPClient(&redis.Options{
- Addr: addr,
- Password: "",
- DB: 0,
- PoolSize: utils.Cfg.RedisSettings.MaxOpenConns,
- })
-
- l4g.Info("Pinging redis at '%v'", addr)
- pong, err := client.Ping().Result()
-
- if err != nil {
- l4g.Critical("Failed to open redis connection to '%v' err:%v", addr, err)
- time.Sleep(time.Second)
- panic("Failed to open redis connection " + err.Error())
- }
-
- if pong != "PONG" {
- l4g.Critical("Failed to ping redis connection to '%v' err:%v", addr, err)
- time.Sleep(time.Second)
- panic("Failed to open ping connection " + err.Error())
- }
- }
-
- return client
-}
-
-func RedisClose() {
- l4g.Info("Closing redis")
-
- if client != nil {
- client.Close()
- client = nil
- }
-}
-
-func PublishAndForget(message *model.Message) {
-
- go func() {
- c := RedisClient()
- result := c.Publish(message.TeamId, message.ToJson())
- if result.Err() != nil {
- l4g.Error("Failed to publish message err=%v, payload=%v", result.Err(), message.ToJson())
- }
- }()
-}
-
-func GetMessageFromPayload(m interface{}) *model.Message {
- if msg, found := m.(*redis.Message); found {
- return model.MessageFromJson(strings.NewReader(msg.Payload))
- } else {
- return nil
- }
-}
diff --git a/store/redis_test.go b/store/redis_test.go
deleted file mode 100644
index 11bd9ca6a..000000000
--- a/store/redis_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package store
-
-import (
- "fmt"
- "github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "testing"
-)
-
-func TestRedis(t *testing.T) {
- utils.LoadConfig("config.json")
-
- c := RedisClient()
-
- if c == nil {
- t.Fatal("should have a valid redis connection")
- }
-
- pubsub := c.PubSub()
- defer pubsub.Close()
-
- m := model.NewMessage(model.NewId(), model.NewId(), model.NewId(), model.ACTION_TYPING)
- m.Add("RootId", model.NewId())
-
- err := pubsub.Subscribe(m.TeamId)
- if err != nil {
- t.Fatal(err)
- }
-
- // should be the subscribe success message
- // lets gobble that up
- if _, err := pubsub.Receive(); err != nil {
- t.Fatal(err)
- }
-
- PublishAndForget(m)
-
- fmt.Println("here1")
-
- if msg, err := pubsub.Receive(); err != nil {
- t.Fatal(err)
- } else {
-
- rmsg := GetMessageFromPayload(msg)
-
- if m.TeamId != rmsg.TeamId {
- t.Fatal("Ids do not match")
- }
-
- if m.Props["RootId"] != rmsg.Props["RootId"] {
- t.Fatal("Ids do not match")
- }
- }
-
- RedisClose()
-}
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index d61fbcdd0..6820b2326 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -81,11 +81,11 @@ func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
dupChannel := model.Channel{}
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId=? AND Name=? AND DeleteAt > 0", channel.TeamId, channel.Name)
- if (dupChannel.DeleteAt > 0) {
+ if dupChannel.DeleteAt > 0 {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
- }
+ }
} else {
result.Err = model.NewAppError("SqlChannelStore.Save", "We couldn't save the channel", "id="+channel.Id+", "+err.Error())
}
@@ -119,7 +119,7 @@ func (s SqlChannelStore) Update(channel *model.Channel) StoreChannel {
if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
dupChannel := model.Channel{}
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId=? AND Name=? AND DeleteAt > 0", channel.TeamId, channel.Name)
- if (dupChannel.DeleteAt > 0) {
+ if dupChannel.DeleteAt > 0 {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
@@ -358,7 +358,7 @@ func (s SqlChannelStore) GetExtraMembers(channelId string, limit int) StoreChann
result := StoreResult{}
var members []model.ExtraMember
- _, err := s.GetReplica().Select(&members, "SELECT Id, FullName, Email, ChannelMembers.Roles, Username FROM ChannelMembers, Users WHERE ChannelMembers.UserId = Users.Id AND ChannelId = ? LIMIT ?", channelId, limit)
+ _, err := s.GetReplica().Select(&members, "SELECT Id, Nickname, Email, ChannelMembers.Roles, Username FROM ChannelMembers, Users WHERE ChannelMembers.UserId = Users.Id AND ChannelId = ? LIMIT ?", channelId, limit)
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetExtraMembers", "We couldn't get the extra info for channel members", "channel_id="+channelId+", "+err.Error())
} else {
diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go
index 9821e9ad0..9cc1c2b06 100644
--- a/store/sql_channel_store_test.go
+++ b/store/sql_channel_store_test.go
@@ -200,13 +200,13 @@ func TestChannelMemberStore(t *testing.T) {
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
- u1.FullName = model.NewId()
+ u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
u2 := model.User{}
u2.TeamId = model.NewId()
u2.Email = model.NewId()
- u2.FullName = model.NewId()
+ u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
o1 := model.ChannelMember{}
diff --git a/store/sql_store.go b/store/sql_store.go
index 7a2d059b9..2e4981e6b 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -126,9 +126,9 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
return dbmap
}
-func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
count, err := ss.GetMaster().SelectInt(
- `SELECT
+ `SELECT
COUNT(0) AS column_exists
FROM
information_schema.COLUMNS
@@ -145,11 +145,15 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
panic("Failed to check if column exists " + err.Error())
}
- if count > 0 {
+ return count > 0
+}
+
+func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+ if ss.DoesColumnExist(tableName, columnName) {
return false
}
- _, err = ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + colType + " DEFAULT '" + defaultValue + "'" + " AFTER " + afterName)
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + colType + " DEFAULT '" + defaultValue + "'" + " AFTER " + afterName)
if err != nil {
l4g.Critical("Failed to create column %v", err)
time.Sleep(time.Second)
@@ -160,31 +164,32 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
}
func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
- count, err := ss.GetMaster().SelectInt(
- `SELECT
- COUNT(0) AS column_exists
- FROM
- information_schema.COLUMNS
- WHERE
- TABLE_SCHEMA = DATABASE()
- AND TABLE_NAME = ?
- AND COLUMN_NAME = ?`,
- tableName,
- columnName,
- )
+ if !ss.DoesColumnExist(tableName, columnName) {
+ return false
+ }
+
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
if err != nil {
- l4g.Critical("Failed to check if column exists %v", err)
+ l4g.Critical("Failed to drop column %v", err)
time.Sleep(time.Second)
- panic("Failed to check if column exists " + err.Error())
+ panic("Failed to drop column " + err.Error())
}
- if count == 0 {
+ return true
+}
+
+func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool {
+ if !ss.DoesColumnExist(tableName, oldColumnName) {
return false
}
- _, err = ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " CHANGE " + oldColumnName + " " + newColumnName + " " + colType)
+
+ // when we eventually support PostgreSQL, we can use the following instead
+ //_, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " RENAME COLUMN " + oldColumnName + " TO " + newColumnName)
+
if err != nil {
- l4g.Critical("Failed to drop column %v", err)
+ l4g.Critical("Failed to rename column %v", err)
time.Sleep(time.Second)
panic("Failed to drop column " + err.Error())
}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index 665e4d697..d8ab4482e 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -25,7 +25,9 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
table.ColMap("Password").SetMaxSize(128)
table.ColMap("AuthData").SetMaxSize(128)
table.ColMap("Email").SetMaxSize(128)
- table.ColMap("FullName").SetMaxSize(64)
+ table.ColMap("Nickname").SetMaxSize(64)
+ table.ColMap("FirstName").SetMaxSize(64)
+ table.ColMap("LastName").SetMaxSize(64)
table.ColMap("Roles").SetMaxSize(64)
table.ColMap("Props").SetMaxSize(4000)
table.ColMap("NotifyProps").SetMaxSize(2000)
@@ -36,10 +38,29 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
return us
}
-func (s SqlUserStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("Users","LastPictureUpdate", "LastPasswordUpdate", "bigint(20)", "0")
+func (us SqlUserStore) UpgradeSchemaIfNeeded() {
+ us.CreateColumnIfNotExists("Users", "LastPictureUpdate", "LastPasswordUpdate", "bigint(20)", "0")
+
+ // migrating the FullName column to Nickname and adding the FirstName and LastName columns for MM-825
+ if us.RenameColumnIfExists("Users", "FullName", "Nickname", "varchar(64)") {
+ us.CreateColumnIfNotExists("Users", "FirstName", "Nickname", "varchar(64)", "")
+ us.CreateColumnIfNotExists("Users", "LastName", "FirstName", "varchar(64)", "")
+
+ // infer values of first and last name by splitting the previous full name
+ if _, err := us.GetMaster().Exec("UPDATE Users SET FirstName = SUBSTRING_INDEX(SUBSTRING_INDEX(Nickname, ' ', 1), ' ', -1)"); err != nil {
+ panic("Failed to set first name from nickname " + err.Error())
+ }
+
+ // only set the last name from full names that are comprised of multiple words (ie that have at least one space in them)
+ if _, err := us.GetMaster().Exec("Update Users SET LastName = SUBSTRING(Nickname, INSTR(Nickname, ' ') + 1) " +
+ "WHERE CHAR_LENGTH(REPLACE(Nickname, ' ', '')) < CHAR_LENGTH(Nickname)"); err != nil {
+ panic("Failed to set last name from nickname " + err.Error())
+ }
+ }
}
+//func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+
func (us SqlUserStore) CreateIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_team_id", "Users", "TeamId")
}