summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
Diffstat (limited to 'store')
-rw-r--r--store/sql_audit_store.go6
-rw-r--r--store/sql_channel_store.go108
-rw-r--r--store/sql_channel_store_test.go2
-rw-r--r--store/sql_post_store.go106
-rw-r--r--store/sql_post_store_test.go17
-rw-r--r--store/sql_session_store.go11
-rw-r--r--store/sql_store.go9
-rw-r--r--store/sql_team_store.go13
-rw-r--r--store/sql_user_store.go32
9 files changed, 186 insertions, 118 deletions
diff --git a/store/sql_audit_store.go b/store/sql_audit_store.go
index dd9312007..a595d50e2 100644
--- a/store/sql_audit_store.go
+++ b/store/sql_audit_store.go
@@ -31,7 +31,7 @@ func (s SqlAuditStore) UpgradeSchemaIfNeeded() {
}
func (s SqlAuditStore) CreateIndexesIfNotExists() {
- s.CreateIndexIfNotExists("idx_user_id", "Audits", "UserId")
+ s.CreateIndexIfNotExists("idx_audits_user_id", "Audits", "UserId")
}
func (s SqlAuditStore) Save(audit *model.Audit) StoreChannel {
@@ -73,8 +73,8 @@ func (s SqlAuditStore) Get(user_id string, limit int) StoreChannel {
}
var audits model.Audits
- if _, err := s.GetReplica().Select(&audits, "SELECT * FROM Audits WHERE UserId = ? ORDER BY CreateAt DESC LIMIT ?",
- user_id, limit); err != nil {
+ if _, err := s.GetReplica().Select(&audits, "SELECT * FROM Audits WHERE UserId = :user_id ORDER BY CreateAt DESC LIMIT :limit",
+ map[string]interface{}{"user_id": user_id, "limit": limit}); err != nil {
result.Err = model.NewAppError("SqlAuditStore.Get", "We encounted an error finding the audits", "user_id="+user_id)
} else {
result.Data = audits
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index 6820b2326..dbdfc16b1 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -6,7 +6,6 @@ package store
import (
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
- "strings"
)
type SqlChannelStore struct {
@@ -37,11 +36,14 @@ func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
}
func (s SqlChannelStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("ChannelMembers", "LastUpdateAt", "NotifyLevel", "bigint(20)", "0") // Remove after 6/7/2015 prod push
}
func (s SqlChannelStore) CreateIndexesIfNotExists() {
- s.CreateIndexIfNotExists("idx_team_id", "Channels", "TeamId")
+ s.CreateIndexIfNotExists("idx_channels_team_id", "Channels", "TeamId")
+ s.CreateIndexIfNotExists("idx_channels_name", "Channels", "Name")
+
+ s.CreateIndexIfNotExists("idx_channelmembers_channel_id", "ChannelMembers", "ChannelId")
+ s.CreateIndexIfNotExists("idx_channelmembers_user_id", "ChannelMembers", "UserId")
}
func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
@@ -65,7 +67,7 @@ func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
return
}
- if count, err := s.GetMaster().SelectInt("SELECT COUNT(0) FROM Channels WHERE TeamId = ? AND DeleteAt = 0 AND (Type ='O' || Type ='P')", channel.TeamId); err != nil {
+ if count, err := s.GetMaster().SelectInt("SELECT COUNT(0) FROM Channels WHERE TeamId = :TeamId AND DeleteAt = 0 AND (Type = 'O' OR Type = 'P')", map[string]interface{}{"TeamId": channel.TeamId}); err != nil {
result.Err = model.NewAppError("SqlChannelStore.Save", "Failed to get current channel count", "teamId="+channel.TeamId+", "+err.Error())
storeChannel <- result
close(storeChannel)
@@ -78,7 +80,7 @@ func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
}
if err := s.GetMaster().Insert(channel); err != nil {
- if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
+ if IsUniqueConstraintError(err.Error(), "Name", "channels_name_teamid_key") {
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 {
@@ -116,7 +118,7 @@ func (s SqlChannelStore) Update(channel *model.Channel) StoreChannel {
}
if count, err := s.GetMaster().Update(channel); err != nil {
- if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
+ if IsUniqueConstraintError(err.Error(), "Name", "channels_name_teamid_key") {
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 {
@@ -167,7 +169,7 @@ func (s SqlChannelStore) Delete(channelId string, time int64) StoreChannel {
go func() {
result := StoreResult{}
- _, err := s.GetMaster().Exec("Update Channels SET DeleteAt = ?, UpdateAt = ? WHERE Id = ?", time, time, channelId)
+ _, err := s.GetMaster().Exec("Update Channels SET DeleteAt = "+s.GetMaster().Dialect.BindVar(0)+", UpdateAt = "+s.GetMaster().Dialect.BindVar(1)+" WHERE Id = "+s.GetMaster().Dialect.BindVar(2), time, time, channelId)
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.Delete", "We couldn't delete the channel", "id="+channelId+", err="+err.Error())
}
@@ -191,7 +193,7 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string) StoreChannel
result := StoreResult{}
var data []channelWithMember
- _, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND TeamId = ? AND UserId = ? AND DeleteAt = 0 ORDER BY DisplayName", teamId, userId)
+ _, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND TeamId = :TeamId AND UserId = :UserId AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetChannels", "We couldn't get the channels", "teamId="+teamId+", userId="+userId+", err="+err.Error())
@@ -230,8 +232,8 @@ func (s SqlChannelStore) GetMoreChannels(teamId string, userId string) StoreChan
FROM
Channels
WHERE
- TeamId = ?
- AND Type IN ("O")
+ TeamId = :TeamId1
+ AND Type IN ('O')
AND DeleteAt = 0
AND Id NOT IN (SELECT
Channels.Id
@@ -240,11 +242,11 @@ func (s SqlChannelStore) GetMoreChannels(teamId string, userId string) StoreChan
ChannelMembers
WHERE
Id = ChannelId
- AND TeamId = ?
- AND UserId = ?
+ AND TeamId = :TeamId2
+ AND UserId = :UserId
AND DeleteAt = 0)
ORDER BY DisplayName`,
- teamId, teamId, userId)
+ map[string]interface{}{"TeamId1": teamId, "TeamId2": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetMoreChannels", "We couldn't get the channels", "teamId="+teamId+", userId="+userId+", err="+err.Error())
@@ -267,7 +269,7 @@ func (s SqlChannelStore) GetByName(teamId string, name string) StoreChannel {
channel := model.Channel{}
- if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE TeamId=? AND Name=? AND DeleteAt = 0", teamId, name); err != nil {
+ if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE TeamId = :TeamId AND Name= :Name AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId, "Name": name}); err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetByName", "We couldn't find the existing channel", "teamId="+teamId+", "+"name="+name+", "+err.Error())
} else {
result.Data = &channel
@@ -293,7 +295,7 @@ func (s SqlChannelStore) SaveMember(member *model.ChannelMember) StoreChannel {
}
if err := s.GetMaster().Insert(member); err != nil {
- if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'ChannelId'") {
+ if IsUniqueConstraintError(err.Error(), "ChannelId", "channelmembers_pkey") {
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "A channel member with that id already exists", "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "We couldn't save the channel member", "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error())
@@ -316,7 +318,7 @@ func (s SqlChannelStore) GetMembers(channelId string) StoreChannel {
result := StoreResult{}
var members []model.ChannelMember
- _, err := s.GetReplica().Select(&members, "SELECT * FROM ChannelMembers WHERE ChannelId = ?", channelId)
+ _, err := s.GetReplica().Select(&members, "SELECT * FROM ChannelMembers WHERE ChannelId = :ChannelId", map[string]interface{}{"ChannelId": channelId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetMembers", "We couldn't get the channel members", "channel_id="+channelId+err.Error())
} else {
@@ -337,7 +339,7 @@ func (s SqlChannelStore) GetMember(channelId string, userId string) StoreChannel
result := StoreResult{}
var member model.ChannelMember
- err := s.GetReplica().SelectOne(&member, "SELECT * FROM ChannelMembers WHERE ChannelId = ? AND UserId = ?", channelId, userId)
+ err := s.GetReplica().SelectOne(&member, "SELECT * FROM ChannelMembers WHERE ChannelId = :ChannelId AND UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetMember", "We couldn't get the channel member", "channel_id="+channelId+"user_id="+userId+","+err.Error())
} else {
@@ -358,7 +360,7 @@ func (s SqlChannelStore) GetExtraMembers(channelId string, limit int) StoreChann
result := StoreResult{}
var members []model.ExtraMember
- _, 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)
+ _, err := s.GetReplica().Select(&members, "SELECT Id, Nickname, Email, ChannelMembers.Roles, Username FROM ChannelMembers, Users WHERE ChannelMembers.UserId = Users.Id AND ChannelId = :ChannelId LIMIT :Limit", map[string]interface{}{"ChannelId": channelId, "Limit": 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 {
@@ -381,7 +383,7 @@ func (s SqlChannelStore) RemoveMember(channelId string, userId string) StoreChan
go func() {
result := StoreResult{}
- _, err := s.GetMaster().Exec("DELETE FROM ChannelMembers WHERE ChannelId = ? AND UserId = ?", channelId, userId)
+ _, err := s.GetMaster().Exec("DELETE FROM ChannelMembers WHERE ChannelId = :ChannelId AND UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "We couldn't remove the channel member", "channel_id="+channelId+", user_id="+userId+", "+err.Error())
}
@@ -407,11 +409,11 @@ func (s SqlChannelStore) CheckPermissionsTo(teamId string, channelId string, use
ChannelMembers
WHERE
Channels.Id = ChannelMembers.ChannelId
- AND Channels.TeamId = ?
+ AND Channels.TeamId = :TeamId
AND Channels.DeleteAt = 0
- AND ChannelMembers.ChannelId = ?
- AND ChannelMembers.UserId = ?`,
- teamId, channelId, userId)
+ AND ChannelMembers.ChannelId = :ChannelId
+ AND ChannelMembers.UserId = :UserId`,
+ map[string]interface{}{"TeamId": teamId, "ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.CheckPermissionsTo", "We couldn't check the permissions", "channel_id="+channelId+", user_id="+userId+", "+err.Error())
} else {
@@ -439,11 +441,11 @@ func (s SqlChannelStore) CheckPermissionsToByName(teamId string, channelName str
ChannelMembers
WHERE
Channels.Id = ChannelMembers.ChannelId
- AND Channels.TeamId = ?
- AND Channels.Name = ?
+ AND Channels.TeamId = :TeamId
+ AND Channels.Name = :Name
AND Channels.DeleteAt = 0
- AND ChannelMembers.UserId = ?`,
- teamId, channelName, userId)
+ AND ChannelMembers.UserId = :UserId`,
+ map[string]interface{}{"TeamId": teamId, "Name": channelName, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.CheckPermissionsToByName", "We couldn't check the permissions", "channel_id="+channelName+", user_id="+userId+", "+err.Error())
} else {
@@ -469,10 +471,10 @@ func (s SqlChannelStore) CheckOpenChannelPermissions(teamId string, channelId st
FROM
Channels
WHERE
- Channels.Id = ?
- AND Channels.TeamId = ?
- AND Channels.Type = ?`,
- channelId, teamId, model.CHANNEL_OPEN)
+ Channels.Id = :ChannelId
+ AND Channels.TeamId = :TeamId
+ AND Channels.Type = :ChannelType`,
+ map[string]interface{}{"ChannelId": channelId, "TeamId": teamId, "ChannelType": model.CHANNEL_OPEN})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.CheckOpenChannelPermissions", "We couldn't check the permissions", "channel_id="+channelId+", "+err.Error())
} else {
@@ -492,8 +494,24 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelId string, userId string) Sto
go func() {
result := StoreResult{}
- _, err := s.GetMaster().Exec(
- `UPDATE
+ var query string
+
+ if utils.Cfg.SqlSettings.DriverName == "postgres" {
+ query = `UPDATE
+ ChannelMembers
+ SET
+ MentionCount = 0,
+ MsgCount = Channels.TotalMsgCount,
+ LastViewedAt = Channels.LastPostAt,
+ LastUpdateAt = Channels.LastPostAt
+ FROM
+ Channels
+ WHERE
+ Channels.Id = ChannelMembers.ChannelId
+ AND UserId = :UserId
+ AND ChannelId = :ChannelId`
+ } else if utils.Cfg.SqlSettings.DriverName == "mysql" {
+ query = `UPDATE
ChannelMembers, Channels
SET
ChannelMembers.MentionCount = 0,
@@ -502,9 +520,11 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelId string, userId string) Sto
ChannelMembers.LastUpdateAt = Channels.LastPostAt
WHERE
Channels.Id = ChannelMembers.ChannelId
- AND UserId = ?
- AND ChannelId = ?`,
- userId, channelId)
+ AND UserId = :UserId
+ AND ChannelId = :ChannelId`
+ }
+
+ _, err := s.GetMaster().Exec(query, map[string]interface{}{"ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.UpdateLastViewedAt", "We couldn't update the last viewed at time", "channel_id="+channelId+", user_id="+userId+", "+err.Error())
}
@@ -528,9 +548,9 @@ func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string)
SET
MentionCount = MentionCount + 1
WHERE
- UserId = ?
- AND ChannelId = ?`,
- userId, channelId)
+ UserId = :UserId
+ AND ChannelId = :ChannelId`,
+ map[string]interface{}{"ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.IncrementMentionCount", "We couldn't increment the mention count", "channel_id="+channelId+", user_id="+userId+", "+err.Error())
}
@@ -554,12 +574,12 @@ func (s SqlChannelStore) UpdateNotifyLevel(channelId, userId, notifyLevel string
`UPDATE
ChannelMembers
SET
- NotifyLevel = ?,
- LastUpdateAt = ?
+ NotifyLevel = :NotifyLevel,
+ LastUpdateAt = :LastUpdateAt
WHERE
- UserId = ?
- AND ChannelId = ?`,
- notifyLevel, updateAt, userId, channelId)
+ UserId = :UserId
+ AND ChannelId = :ChannelId`,
+ map[string]interface{}{"ChannelId": channelId, "UserId": userId, "NotifyLevel": notifyLevel, "LastUpdateAt": updateAt})
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.UpdateNotifyLevel", "We couldn't update the notify level", "channel_id="+channelId+", user_id="+userId+", "+err.Error())
}
diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go
index 9cc1c2b06..ae29bc2b3 100644
--- a/store/sql_channel_store_test.go
+++ b/store/sql_channel_store_test.go
@@ -451,7 +451,7 @@ func TestChannelStoreUpdateLastViewedAt(t *testing.T) {
err := (<-store.Channel().UpdateLastViewedAt(m1.ChannelId, m1.UserId)).Err
if err != nil {
- t.Fatal("failed to update")
+ t.Fatal("failed to update", err)
}
err = (<-store.Channel().UpdateLastViewedAt(m1.ChannelId, "missing id")).Err
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index 5b9ebfdf2..56c174e4c 100644
--- a/store/sql_post_store.go
+++ b/store/sql_post_store.go
@@ -6,6 +6,7 @@ package store
import (
"fmt"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
"strconv"
"strings"
)
@@ -43,13 +44,13 @@ func (s SqlPostStore) UpgradeSchemaIfNeeded() {
}
func (s SqlPostStore) CreateIndexesIfNotExists() {
- s.CreateIndexIfNotExists("idx_update_at", "Posts", "UpdateAt")
- s.CreateIndexIfNotExists("idx_create_at", "Posts", "CreateAt")
- s.CreateIndexIfNotExists("idx_channel_id", "Posts", "ChannelId")
- s.CreateIndexIfNotExists("idx_root_id", "Posts", "RootId")
+ s.CreateIndexIfNotExists("idx_posts_update_at", "Posts", "UpdateAt")
+ s.CreateIndexIfNotExists("idx_posts_create_at", "Posts", "CreateAt")
+ s.CreateIndexIfNotExists("idx_posts_channel_id", "Posts", "ChannelId")
+ s.CreateIndexIfNotExists("idx_posts_root_id", "Posts", "RootId")
- s.CreateFullTextIndexIfNotExists("idx_message_txt", "Posts", "Message")
- s.CreateFullTextIndexIfNotExists("idx_hashtags_txt", "Posts", "Hashtags")
+ s.CreateFullTextIndexIfNotExists("idx_posts_message_txt", "Posts", "Message")
+ s.CreateFullTextIndexIfNotExists("idx_posts_hashtags_txt", "Posts", "Hashtags")
}
func (s SqlPostStore) Save(post *model.Post) StoreChannel {
@@ -152,7 +153,7 @@ func (s SqlPostStore) Get(id string) StoreChannel {
pl := &model.PostList{}
var post model.Post
- err := s.GetReplica().SelectOne(&post, "SELECT * FROM Posts WHERE Id = ? AND DeleteAt = 0", id)
+ err := s.GetReplica().SelectOne(&post, "SELECT * FROM Posts WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.GetPost", "We couldn't get the post", "id="+id+err.Error())
}
@@ -175,7 +176,7 @@ func (s SqlPostStore) Get(id string) StoreChannel {
}
var posts []*model.Post
- _, err = s.GetReplica().Select(&posts, "SELECT * FROM Posts WHERE (Id = ? OR RootId = ?) AND DeleteAt = 0", rootId, rootId)
+ _, err = s.GetReplica().Select(&posts, "SELECT * FROM Posts WHERE (Id = :Id OR RootId = :RootId) AND DeleteAt = 0", map[string]interface{}{"Id": rootId, "RootId": rootId})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.GetPost", "We couldn't get the post", "root_id="+rootId+err.Error())
} else {
@@ -205,7 +206,7 @@ func (s SqlPostStore) GetEtag(channelId string) StoreChannel {
result := StoreResult{}
var et etagPosts
- err := s.GetReplica().SelectOne(&et, "SELECT Id, UpdateAt FROM Posts WHERE ChannelId = ? ORDER BY UpdateAt DESC LIMIT 1", channelId)
+ err := s.GetReplica().SelectOne(&et, "SELECT Id, UpdateAt FROM Posts WHERE ChannelId = :ChannelId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"ChannelId": channelId})
if err != nil {
result.Data = fmt.Sprintf("%v.0.%v", model.ETAG_ROOT_VERSION, model.GetMillis())
} else {
@@ -225,7 +226,7 @@ func (s SqlPostStore) Delete(postId string, time int64) StoreChannel {
go func() {
result := StoreResult{}
- _, err := s.GetMaster().Exec("Update Posts SET DeleteAt = ?, UpdateAt = ? WHERE Id = ? OR ParentId = ? OR RootId = ?", time, time, postId, postId, postId)
+ _, err := s.GetMaster().Exec("Update Posts SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id OR ParentId = :ParentId OR RootId = :RootId", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": postId, "ParentId": postId, "RootId": postId})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.Delete", "We couldn't delete the post", "id="+postId+", err="+err.Error())
}
@@ -305,7 +306,7 @@ func (s SqlPostStore) getRootPosts(channelId string, offset int, limit int) Stor
result := StoreResult{}
var posts []*model.Post
- _, err := s.GetReplica().Select(&posts, "SELECT * FROM Posts WHERE ChannelId = ? AND DeleteAt = 0 ORDER BY CreateAt DESC LIMIT ?,?", channelId, offset, limit)
+ _, err := s.GetReplica().Select(&posts, "SELECT * FROM Posts WHERE ChannelId = :ChannelId AND DeleteAt = 0 ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset", map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.GetLinearPosts", "We couldn't get the posts for the channel", "channelId="+channelId+err.Error())
} else {
@@ -340,15 +341,15 @@ func (s SqlPostStore) getParentsPosts(channelId string, offset int, limit int) S
FROM
Posts
WHERE
- ChannelId = ?
+ ChannelId = :ChannelId1
AND DeleteAt = 0
ORDER BY CreateAt DESC
- LIMIT ?, ?) q3) q1 ON q1.RootId = q2.RootId
+ LIMIT :Limit OFFSET :Offset) q3) q1 ON q1.RootId = q2.RootId
WHERE
- ChannelId = ?
+ ChannelId = :ChannelId2
AND DeleteAt = 0
ORDER BY CreateAt`,
- channelId, offset, limit, channelId)
+ map[string]interface{}{"ChannelId1": channelId, "Offset": offset, "Limit": limit, "ChannelId2": channelId})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.GetLinearPosts", "We couldn't get the parent post for the channel", "channelId="+channelId+err.Error())
} else {
@@ -382,7 +383,37 @@ func (s SqlPostStore) Search(teamId string, userId string, terms string, isHasht
// cannot escape it so we replace it.
terms = strings.Replace(terms, "@", " ", -1)
- searchQuery := fmt.Sprintf(`SELECT
+ var posts []*model.Post
+
+ if utils.Cfg.SqlSettings.DriverName == "postgres" {
+ searchQuery := fmt.Sprintf(`SELECT
+ *
+ FROM
+ Posts
+ WHERE
+ DeleteAt = 0
+ AND ChannelId IN (SELECT
+ Id
+ FROM
+ Channels,
+ ChannelMembers
+ WHERE
+ Id = ChannelId AND TeamId = $1
+ AND UserId = $2
+ AND DeleteAt = 0)
+ AND %s @@ plainto_tsquery($3)
+ ORDER BY CreateAt DESC
+ LIMIT 100`, searchType)
+
+ terms = strings.Join(strings.Fields(terms), " | ")
+
+ _, err := s.GetReplica().Select(&posts, searchQuery, teamId, userId, terms)
+ if err != nil {
+ result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
+
+ }
+ } else if utils.Cfg.SqlSettings.DriverName == "mysql" {
+ searchQuery := fmt.Sprintf(`SELECT
*
FROM
Posts
@@ -401,34 +432,35 @@ func (s SqlPostStore) Search(teamId string, userId string, terms string, isHasht
ORDER BY CreateAt DESC
LIMIT 100`, searchType)
- var posts []*model.Post
- _, err := s.GetReplica().Select(&posts, searchQuery, teamId, userId, terms)
- if err != nil {
- result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
- } else {
+ _, err := s.GetReplica().Select(&posts, searchQuery, teamId, userId, terms)
+ if err != nil {
+ result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
- list := &model.PostList{Order: make([]string, 0, len(posts))}
+ }
+ }
- for _, p := range posts {
- if searchType == "Hashtags" {
- exactMatch := false
- for _, tag := range strings.Split(p.Hashtags, " ") {
- if termMap[tag] {
- exactMatch = true
- }
- }
- if !exactMatch {
- continue
+ list := &model.PostList{Order: make([]string, 0, len(posts))}
+
+ for _, p := range posts {
+ if searchType == "Hashtags" {
+ exactMatch := false
+ for _, tag := range strings.Split(p.Hashtags, " ") {
+ if termMap[tag] {
+ exactMatch = true
}
}
- list.AddPost(p)
- list.AddOrder(p.Id)
+ if !exactMatch {
+ continue
+ }
}
+ list.AddPost(p)
+ list.AddOrder(p.Id)
+ }
- list.MakeNonNil()
+ list.MakeNonNil()
+
+ result.Data = list
- result.Data = list
- }
storeChannel <- result
close(storeChannel)
}()
diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go
index d9805eb02..bad6408b8 100644
--- a/store/sql_post_store_test.go
+++ b/store/sql_post_store_test.go
@@ -5,6 +5,7 @@ package store
import (
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
"strings"
"testing"
"time"
@@ -444,9 +445,11 @@ func TestPostStoreSearch(t *testing.T) {
t.Fatal("returned wrong serach result")
}
- r2 := (<-store.Post().Search(teamId, userId, "new york", false)).Data.(*model.PostList)
- if len(r2.Order) != 2 && r2.Order[0] != o2.Id {
- t.Fatal("returned wrong serach result")
+ if utils.Cfg.SqlSettings.DriverName == "mysql" {
+ r2 := (<-store.Post().Search(teamId, userId, "new york", false)).Data.(*model.PostList)
+ if len(r2.Order) >= 1 && r2.Order[0] != o2.Id {
+ t.Fatal("returned wrong serach result")
+ }
}
r3 := (<-store.Post().Search(teamId, userId, "new", false)).Data.(*model.PostList)
@@ -459,9 +462,11 @@ func TestPostStoreSearch(t *testing.T) {
t.Fatal("returned wrong serach result")
}
- r5 := (<-store.Post().Search(teamId, userId, "matter*", false)).Data.(*model.PostList)
- if len(r5.Order) != 1 && r5.Order[0] != o1.Id {
- t.Fatal("returned wrong serach result")
+ if utils.Cfg.SqlSettings.DriverName == "mysql" {
+ r5 := (<-store.Post().Search(teamId, userId, "matter*", false)).Data.(*model.PostList)
+ if len(r5.Order) != 1 && r5.Order[0] != o1.Id {
+ t.Fatal("returned wrong serach result")
+ }
}
r6 := (<-store.Post().Search(teamId, userId, "#hashtag", true)).Data.(*model.PostList)
diff --git a/store/sql_session_store.go b/store/sql_session_store.go
index dddd023e5..d1a06a33c 100644
--- a/store/sql_session_store.go
+++ b/store/sql_session_store.go
@@ -33,7 +33,8 @@ func (me SqlSessionStore) UpgradeSchemaIfNeeded() {
}
func (me SqlSessionStore) CreateIndexesIfNotExists() {
- me.CreateIndexIfNotExists("idx_user_id", "Sessions", "UserId")
+ me.CreateIndexIfNotExists("idx_sessions_user_id", "Sessions", "UserId")
+ me.CreateIndexIfNotExists("idx_sessions_alt_id", "Sessions", "AltId")
}
func (me SqlSessionStore) Save(session *model.Session) StoreChannel {
@@ -105,7 +106,7 @@ func (me SqlSessionStore) GetSessions(userId string) StoreChannel {
var sessions []*model.Session
- if _, err := me.GetReplica().Select(&sessions, "SELECT * FROM Sessions WHERE UserId = ? ORDER BY LastActivityAt DESC", userId); err != nil {
+ if _, err := me.GetReplica().Select(&sessions, "SELECT * FROM Sessions WHERE UserId = :UserId ORDER BY LastActivityAt DESC", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewAppError("SqlSessionStore.GetSessions", "We encounted an error while finding user sessions", err.Error())
} else {
@@ -125,7 +126,7 @@ func (me SqlSessionStore) Remove(sessionIdOrAlt string) StoreChannel {
go func() {
result := StoreResult{}
- _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE Id = ? Or AltId = ?", sessionIdOrAlt, sessionIdOrAlt)
+ _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE Id = :Id Or AltId = :AltId", map[string]interface{}{"Id": sessionIdOrAlt, "AltId": sessionIdOrAlt})
if err != nil {
result.Err = model.NewAppError("SqlSessionStore.RemoveSession", "We couldn't remove the session", "id="+sessionIdOrAlt+", err="+err.Error())
}
@@ -143,7 +144,7 @@ func (me SqlSessionStore) CleanUpExpiredSessions(userId string) StoreChannel {
go func() {
result := StoreResult{}
- if _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE UserId = ? AND ExpiresAt != 0 AND ? > ExpiresAt", userId, model.GetMillis()); err != nil {
+ if _, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE UserId = :UserId AND ExpiresAt != 0 AND :ExpiresAt > ExpiresAt", map[string]interface{}{"UserId": userId, "ExpiresAt": model.GetMillis()}); err != nil {
result.Err = model.NewAppError("SqlSessionStore.CleanUpExpiredSessions", "We encounted an error while deleting expired user sessions", err.Error())
} else {
result.Data = userId
@@ -162,7 +163,7 @@ func (me SqlSessionStore) UpdateLastActivityAt(sessionId string, time int64) Sto
go func() {
result := StoreResult{}
- if _, err := me.GetMaster().Exec("UPDATE Sessions SET LastActivityAt = ? WHERE Id = ?", time, sessionId); err != nil {
+ if _, err := me.GetMaster().Exec("UPDATE Sessions SET LastActivityAt = :LastActivityAt WHERE Id = :Id", map[string]interface{}{"LastActivityAt": time, "Id": sessionId}); err != nil {
result.Err = model.NewAppError("SqlSessionStore.UpdateLastActivityAt", "We couldn't update the last_activity_at", "sessionId="+sessionId)
} else {
result.Data = sessionId
diff --git a/store/sql_store.go b/store/sql_store.go
index 2e4981e6b..216060dba 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -18,6 +18,7 @@ import (
"fmt"
"github.com/go-gorp/gorp"
_ "github.com/go-sql-driver/mysql"
+ _ "github.com/lib/pq"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"io"
@@ -113,6 +114,8 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
dbmap = &gorp.DbMap{Db: db, TypeConverter: mattermConverter{}, Dialect: gorp.SqliteDialect{}}
} else if driver == "mysql" {
dbmap = &gorp.DbMap{Db: db, TypeConverter: mattermConverter{}, Dialect: gorp.MySQLDialect{Engine: "InnoDB", Encoding: "UTF8MB4"}}
+ } else if driver == "postgres" {
+ dbmap = &gorp.DbMap{Db: db, TypeConverter: mattermConverter{}, Dialect: gorp.PostgresDialect{}}
} else {
l4g.Critical("Failed to create dialect specific driver")
time.Sleep(time.Second)
@@ -230,6 +233,12 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
}
}
+func IsUniqueConstraintError(err string, mysql string, postgres string) bool {
+ unique := strings.Contains(err, "unique constraint") || strings.Contains(err, "Duplicate entry")
+ field := strings.Contains(err, mysql) || strings.Contains(err, postgres)
+ return unique && field
+}
+
func (ss SqlStore) GetMaster() *gorp.DbMap {
return ss.master
}
diff --git a/store/sql_team_store.go b/store/sql_team_store.go
index b89dca03e..73d603151 100644
--- a/store/sql_team_store.go
+++ b/store/sql_team_store.go
@@ -5,8 +5,6 @@ package store
import (
"github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "strings"
)
type SqlTeamStore struct {
@@ -42,6 +40,7 @@ func (s SqlTeamStore) UpgradeSchemaIfNeeded() {
}
func (s SqlTeamStore) CreateIndexesIfNotExists() {
+ s.CreateIndexIfNotExists("idx_teams_domain", "Teams", "Domain")
}
func (s SqlTeamStore) Save(team *model.Team) StoreChannel {
@@ -66,7 +65,7 @@ func (s SqlTeamStore) Save(team *model.Team) StoreChannel {
}
if err := s.GetMaster().Insert(team); err != nil {
- if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
+ if IsUniqueConstraintError(err.Error(), "Name", "teams_domain_key") {
result.Err = model.NewAppError("SqlTeamStore.Save", "A team with that domain already exists", "id="+team.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlTeamStore.Save", "We couldn't save the team", "id="+team.Id+", "+err.Error())
@@ -129,8 +128,8 @@ func (s SqlTeamStore) UpdateDisplayName(name string, teamId string) StoreChannel
go func() {
result := StoreResult{}
- if _, err := s.GetMaster().Exec("UPDATE Teams SET DisplayName = ? WHERE Id = ?", name, teamId); err != nil {
- result.Err = model.NewAppError("SqlTeamStore.UpdateDisplayName", "We couldn't update the team name", "team_id="+teamId)
+ if _, err := s.GetMaster().Exec("UPDATE Teams SET DisplayName = :Name WHERE Id = :Id", map[string]interface{}{"Name": name, "Id": teamId}); err != nil {
+ result.Err = model.NewAppError("SqlTeamStore.UpdateName", "We couldn't update the team name", "team_id="+teamId)
} else {
result.Data = teamId
}
@@ -171,7 +170,7 @@ func (s SqlTeamStore) GetByName(name string) StoreChannel {
team := model.Team{}
- if err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE Name=?", name); err != nil {
+ if err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetByName", "We couldn't find the existing team", "name="+name+", "+err.Error())
}
@@ -191,7 +190,7 @@ func (s SqlTeamStore) GetTeamsForEmail(email string) StoreChannel {
result := StoreResult{}
var data []*model.Team
- if _, err := s.GetReplica().Select(&data, "SELECT Teams.* FROM Teams, Users WHERE Teams.Id = Users.TeamId AND Users.Email = ?", email); err != nil {
+ if _, err := s.GetReplica().Select(&data, "SELECT Teams.* FROM Teams, Users WHERE Teams.Id = Users.TeamId AND Users.Email = :Email", map[string]interface{}{"Email": email}); err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetTeamsForEmail", "We encounted a problem when looking up teams", "email="+email+", "+err.Error())
}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index d8ab4482e..5feef5e69 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -7,7 +7,6 @@ import (
"fmt"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
- "strings"
)
type SqlUserStore struct {
@@ -62,7 +61,8 @@ func (us SqlUserStore) UpgradeSchemaIfNeeded() {
//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")
+ us.CreateIndexIfNotExists("idx_users_team_id", "Users", "TeamId")
+ us.CreateIndexIfNotExists("idx_users_email", "Users", "Email")
}
func (us SqlUserStore) Save(user *model.User) StoreChannel {
@@ -86,7 +86,7 @@ func (us SqlUserStore) Save(user *model.User) StoreChannel {
return
}
- if count, err := us.GetMaster().SelectInt("SELECT COUNT(0) FROM Users WHERE TeamId = ? AND DeleteAt = 0", user.TeamId); err != nil {
+ if count, err := us.GetMaster().SelectInt("SELECT COUNT(0) FROM Users WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": user.TeamId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.Save", "Failed to get current team member count", "teamId="+user.TeamId+", "+err.Error())
storeChannel <- result
close(storeChannel)
@@ -99,9 +99,9 @@ func (us SqlUserStore) Save(user *model.User) StoreChannel {
}
if err := us.GetMaster().Insert(user); err != nil {
- if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Email'") {
+ if IsUniqueConstraintError(err.Error(), "Email", "users_email_teamid_key") {
result.Err = model.NewAppError("SqlUserStore.Save", "An account with that email already exists.", "user_id="+user.Id+", "+err.Error())
- } else if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Username'") {
+ } else if IsUniqueConstraintError(err.Error(), "Username", "users_username_teamid_key") {
result.Err = model.NewAppError("SqlUserStore.Save", "An account with that username already exists.", "user_id="+user.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlUserStore.Save", "We couldn't save the account.", "user_id="+user.Id+", "+err.Error())
@@ -200,7 +200,7 @@ func (us SqlUserStore) UpdateLastPingAt(userId string, time int64) StoreChannel
go func() {
result := StoreResult{}
- if _, err := us.GetMaster().Exec("UPDATE Users SET LastPingAt = ? WHERE Id = ?", time, userId); err != nil {
+ if _, err := us.GetMaster().Exec("UPDATE Users SET LastPingAt = :LastPingAt WHERE Id = :UserId", map[string]interface{}{"LastPingAt": time, "UserId": userId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.UpdateLastPingAt", "We couldn't update the last_ping_at", "user_id="+userId)
} else {
result.Data = userId
@@ -219,7 +219,7 @@ func (us SqlUserStore) UpdateLastActivityAt(userId string, time int64) StoreChan
go func() {
result := StoreResult{}
- if _, err := us.GetMaster().Exec("UPDATE Users SET LastActivityAt = ? WHERE Id = ?", time, userId); err != nil {
+ if _, err := us.GetMaster().Exec("UPDATE Users SET LastActivityAt = :LastActivityAt WHERE Id = :UserId", map[string]interface{}{"LastActivityAt": time, "UserId": userId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.UpdateLastActivityAt", "We couldn't update the last_activity_at", "user_id="+userId)
} else {
result.Data = userId
@@ -238,8 +238,10 @@ func (us SqlUserStore) UpdateUserAndSessionActivity(userId string, sessionId str
go func() {
result := StoreResult{}
- if _, err := us.GetMaster().Exec("UPDATE Sessions, Users SET Users.LastActivityAt = ?, Sessions.LastActivityAt = ? WHERE Users.Id = ? AND Sessions.Id = ?", time, time, userId, sessionId); err != nil {
- result.Err = model.NewAppError("SqlUserStore.UpdateLastActivityAt", "We couldn't update the last_activity_at", "user_id="+userId+" session_id="+sessionId+" err="+err.Error())
+ if _, err := us.GetMaster().Exec("UPDATE Users SET LastActivityAt = :UserLastActivityAt WHERE Id = :UserId", map[string]interface{}{"UserLastActivityAt": time, "UserId": userId}); err != nil {
+ result.Err = model.NewAppError("SqlUserStore.UpdateLastActivityAt", "We couldn't update the last_activity_at", "1 user_id="+userId+" session_id="+sessionId+" err="+err.Error())
+ } else if _, err := us.GetMaster().Exec("UPDATE Sessions SET LastActivityAt = :SessionLastActivityAt WHERE Id = :SessionId", map[string]interface{}{"SessionLastActivityAt": time, "SessionId": sessionId}); err != nil {
+ result.Err = model.NewAppError("SqlUserStore.UpdateLastActivityAt", "We couldn't update the last_activity_at", "2 user_id="+userId+" session_id="+sessionId+" err="+err.Error())
} else {
result.Data = userId
}
@@ -260,7 +262,7 @@ func (us SqlUserStore) UpdatePassword(userId, hashedPassword string) StoreChanne
updateAt := model.GetMillis()
- if _, err := us.GetMaster().Exec("UPDATE Users SET Password = ?, LastPasswordUpdate = ?, UpdateAt = ? WHERE Id = ?", hashedPassword, updateAt, updateAt, userId); err != nil {
+ if _, err := us.GetMaster().Exec("UPDATE Users SET Password = :Password, LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt WHERE Id = :UserId", map[string]interface{}{"Password": hashedPassword, "LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.UpdatePassword", "We couldn't update the user password", "id="+userId+", "+err.Error())
} else {
result.Data = userId
@@ -302,7 +304,7 @@ func (s SqlUserStore) GetEtagForProfiles(teamId string) StoreChannel {
go func() {
result := StoreResult{}
- updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users WHERE TeamId = ? ORDER BY UpdateAt DESC LIMIT 1", teamId)
+ updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users WHERE TeamId = :TeamId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"TeamId": teamId})
if err != nil {
result.Data = fmt.Sprintf("%v.%v", model.ETAG_ROOT_VERSION, model.GetMillis())
} else {
@@ -325,7 +327,7 @@ func (us SqlUserStore) GetProfiles(teamId string) StoreChannel {
var users []*model.User
- if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users WHERE TeamId = ?", teamId); err != nil {
+ if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.GetProfiles", "We encounted an error while finding user profiles", err.Error())
} else {
@@ -356,7 +358,7 @@ func (us SqlUserStore) GetByEmail(teamId string, email string) StoreChannel {
user := model.User{}
- if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId=? AND Email=?", teamId, email); err != nil {
+ if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId = :TeamId AND Email = :Email", map[string]interface{}{"TeamId": teamId, "Email": email}); err != nil {
result.Err = model.NewAppError("SqlUserStore.GetByEmail", "We couldn't find the existing account", "teamId="+teamId+", email="+email+", "+err.Error())
}
@@ -378,7 +380,7 @@ func (us SqlUserStore) GetByUsername(teamId string, username string) StoreChanne
user := model.User{}
- if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId=? AND Username=?", teamId, username); err != nil {
+ if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId = :TeamId AND Username = :Username", map[string]interface{}{"TeamId": teamId, "Username": username}); err != nil {
result.Err = model.NewAppError("SqlUserStore.GetByUsername", "We couldn't find the existing account", "teamId="+teamId+", username="+username+", "+err.Error())
}
@@ -397,7 +399,7 @@ func (us SqlUserStore) VerifyEmail(userId string) StoreChannel {
go func() {
result := StoreResult{}
- if _, err := us.GetMaster().Exec("UPDATE Users SET EmailVerified = 1 WHERE Id = ?", userId); err != nil {
+ if _, err := us.GetMaster().Exec("UPDATE Users SET EmailVerified = '1' WHERE Id = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewAppError("SqlUserStore.VerifyEmail", "Unable to update verify email field", "userId="+userId+", "+err.Error())
}