Moved logic for searching for posts by multiple users/channels into the sql query

Этот коммит содержится в:
hmhealey
2015-10-26 11:45:03 -04:00
родитель 2383d5dd37
Коммит 663bec8147
3 изменённых файлов: 73 добавлений и 49 удалений

Просмотреть файл

@@ -546,6 +546,9 @@ func TestSearchPostsFromUser(t *testing.T) {
Client.Must(Client.JoinChannel(channel1.Id)) Client.Must(Client.JoinChannel(channel1.Id))
Client.Must(Client.JoinChannel(channel2.Id)) Client.Must(Client.JoinChannel(channel2.Id))
// wait for the join/leave messages to be created for user3 since they're done asynchronously
time.Sleep(100 * time.Millisecond)
if result := Client.Must(Client.SearchPosts("from: " + user2.Username)).Data.(*model.PostList); len(result.Order) != 3 { if result := Client.Must(Client.SearchPosts("from: " + user2.Username)).Data.(*model.PostList); len(result.Order) != 3 {
t.Fatalf("wrong number of posts returned %v", len(result.Order)) t.Fatalf("wrong number of posts returned %v", len(result.Order))
} }

Просмотреть файл

@@ -8,10 +8,10 @@ import (
) )
type SearchParams struct { type SearchParams struct {
Terms string Terms string
IsHashtag bool IsHashtag bool
InChannel string InChannels []string
FromUser string FromUsers []string
} }
var searchFlags = [...]string{"from", "channel", "in"} var searchFlags = [...]string{"from", "channel", "in"}
@@ -106,45 +106,34 @@ func ParseSearchParams(text string) []*SearchParams {
} }
} }
if len(inChannels) == 0 {
inChannels = append(inChannels, "")
}
if len(fromUsers) == 0 {
fromUsers = append(fromUsers, "")
}
paramsList := []*SearchParams{} paramsList := []*SearchParams{}
for _, inChannel := range inChannels { if len(plainTerms) > 0 {
for _, fromUser := range fromUsers { paramsList = append(paramsList, &SearchParams{
if len(plainTerms) > 0 { Terms: plainTerms,
paramsList = append(paramsList, &SearchParams{ IsHashtag: false,
Terms: plainTerms, InChannels: inChannels,
IsHashtag: false, FromUsers: fromUsers,
InChannel: inChannel, })
FromUser: fromUser, }
})
}
if len(hashtagTerms) > 0 { if len(hashtagTerms) > 0 {
paramsList = append(paramsList, &SearchParams{ paramsList = append(paramsList, &SearchParams{
Terms: hashtagTerms, Terms: hashtagTerms,
IsHashtag: true, IsHashtag: true,
InChannel: inChannel, InChannels: inChannels,
FromUser: fromUser, FromUsers: fromUsers,
}) })
} }
// special case for when no terms are specified but we still have a filter // special case for when no terms are specified but we still have a filter
if len(plainTerms) == 0 && len(hashtagTerms) == 0 { if len(plainTerms) == 0 && len(hashtagTerms) == 0 {
paramsList = append(paramsList, &SearchParams{ paramsList = append(paramsList, &SearchParams{
Terms: "", Terms: "",
IsHashtag: true, IsHashtag: true,
InChannel: inChannel, InChannels: inChannels,
FromUser: fromUser, FromUsers: fromUsers,
}) })
}
}
} }
return paramsList return paramsList

Просмотреть файл

@@ -6,6 +6,7 @@ package store
import ( import (
"fmt" "fmt"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/mattermost/platform/model" "github.com/mattermost/platform/model"
@@ -413,10 +414,15 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
go func() { go func() {
result := StoreResult{} result := StoreResult{}
queryParams := map[string]interface{}{
"TeamId": teamId,
"UserId": userId,
}
termMap := map[string]bool{} termMap := map[string]bool{}
terms := params.Terms terms := params.Terms
if terms == "" && params.InChannel == "" && params.FromUser == "" { if terms == "" && len(params.InChannels) == 0 && len(params.FromUsers) == 0 {
result.Data = []*model.Post{} result.Data = []*model.Post{}
storeChannel <- result storeChannel <- result
return return
@@ -468,13 +474,45 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
ORDER BY CreateAt DESC ORDER BY CreateAt DESC
LIMIT 100` LIMIT 100`
if params.InChannel != "" { if len(params.InChannels) > 1 {
inClause := ":InChannel0"
queryParams["InChannel0"] = params.InChannels[0]
for i := 1; i < len(params.InChannels); i++ {
paramName := "InChannel" + strconv.FormatInt(int64(i), 10)
inClause += ", :" + paramName
queryParams[paramName] = params.InChannels[i]
}
searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "AND Name IN ("+inClause+")", 1)
} else if len(params.InChannels) == 1 {
queryParams["InChannel"] = params.InChannels[0]
searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "AND Name = :InChannel", 1) searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "AND Name = :InChannel", 1)
} else { } else {
searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "", 1) searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "", 1)
} }
if params.FromUser != "" { if len(params.FromUsers) > 1 {
inClause := ":FromUser0"
queryParams["FromUser0"] = params.FromUsers[0]
for i := 1; i < len(params.FromUsers); i++ {
paramName := "FromUser" + strconv.FormatInt(int64(i), 10)
inClause += ", :" + paramName
queryParams[paramName] = params.FromUsers[i]
}
searchQuery = strings.Replace(searchQuery, "POST_FILTER", `
AND UserId IN (
SELECT
Id
FROM
Users
WHERE
TeamId = :TeamId
AND Username IN (`+inClause+`))`, 1)
} else if len(params.FromUsers) == 1 {
queryParams["FromUser"] = params.FromUsers[0]
searchQuery = strings.Replace(searchQuery, "POST_FILTER", ` searchQuery = strings.Replace(searchQuery, "POST_FILTER", `
AND UserId IN ( AND UserId IN (
SELECT SELECT
@@ -506,13 +544,7 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1) searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1)
} }
queryParams := map[string]interface{}{ queryParams["Terms"] = terms
"TeamId": teamId,
"UserId": userId,
"Terms": terms,
"InChannel": params.InChannel,
"FromUser": params.FromUser,
}
_, err := s.GetReplica().Select(&posts, searchQuery, queryParams) _, err := s.GetReplica().Select(&posts, searchQuery, queryParams)
if err != nil { if err != nil {