Merge pull request #1164 from hmhealey/plt778
PLT-778 Changed post searching to allow searching by multiple users/channels
Этот коммит содержится в:
42
api/post.go
42
api/post.go
@@ -820,45 +820,23 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
plainSearchParams, hashtagSearchParams := model.ParseSearchParams(terms)
|
paramsList := model.ParseSearchParams(terms)
|
||||||
|
channels := []store.StoreChannel{}
|
||||||
|
|
||||||
var hchan store.StoreChannel
|
for _, params := range paramsList {
|
||||||
if hashtagSearchParams != nil {
|
channels = append(channels, Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, params))
|
||||||
hchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, hashtagSearchParams)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var pchan store.StoreChannel
|
posts := &model.PostList{}
|
||||||
if plainSearchParams != nil {
|
for _, channel := range channels {
|
||||||
pchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, plainSearchParams)
|
if result := <-channel; result.Err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
mainList := &model.PostList{}
|
|
||||||
if hchan != nil {
|
|
||||||
if result := <-hchan; result.Err != nil {
|
|
||||||
c.Err = result.Err
|
c.Err = result.Err
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
mainList = result.Data.(*model.PostList)
|
data := result.Data.(*model.PostList)
|
||||||
|
posts.Extend(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plainList := &model.PostList{}
|
w.Write([]byte(posts.ToJson()))
|
||||||
if pchan != nil {
|
|
||||||
if result := <-pchan; result.Err != nil {
|
|
||||||
c.Err = result.Err
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
plainList = result.Data.(*model.PostList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, postId := range plainList.Order {
|
|
||||||
if _, ok := mainList.Posts[postId]; !ok {
|
|
||||||
mainList.AddPost(plainList.Posts[postId])
|
|
||||||
mainList.AddOrder(postId)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte(mainList.ToJson()))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -427,12 +427,18 @@ func TestSearchPostsInChannel(t *testing.T) {
|
|||||||
channel2 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
channel2 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||||
|
|
||||||
|
channel3 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
|
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||||
|
|
||||||
post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
|
post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
|
||||||
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
||||||
|
|
||||||
post3 := &model.Post{ChannelId: channel2.Id, Message: "other message with no return"}
|
post3 := &model.Post{ChannelId: channel2.Id, Message: "other message with no return"}
|
||||||
post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post)
|
post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post)
|
||||||
|
|
||||||
|
post4 := &model.Post{ChannelId: channel3.Id, Message: "other message with no return"}
|
||||||
|
post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
|
||||||
|
|
||||||
if result := Client.Must(Client.SearchPosts("channel:")).Data.(*model.PostList); len(result.Order) != 0 {
|
if result := Client.Must(Client.SearchPosts("channel:")).Data.(*model.PostList); len(result.Order) != 0 {
|
||||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
}
|
}
|
||||||
@@ -476,6 +482,10 @@ func TestSearchPostsInChannel(t *testing.T) {
|
|||||||
if result := Client.Must(Client.SearchPosts("sgtitlereview channel: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 1 {
|
if result := Client.Must(Client.SearchPosts("sgtitlereview channel: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 1 {
|
||||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if result := Client.Must(Client.SearchPosts("channel: " + channel2.Name + " channel: " + channel3.Name)).Data.(*model.PostList); len(result.Order) != 3 {
|
||||||
|
t.Fatalf("wrong number of posts returned :) %v :) %v", result.Posts, result.Order)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearchPostsFromUser(t *testing.T) {
|
func TestSearchPostsFromUser(t *testing.T) {
|
||||||
@@ -510,11 +520,12 @@ func TestSearchPostsFromUser(t *testing.T) {
|
|||||||
post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
|
post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
|
||||||
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
||||||
|
|
||||||
|
// includes "X has joined the channel" messages for both user2 and user3
|
||||||
|
|
||||||
if result := Client.Must(Client.SearchPosts("from: " + user1.Username)).Data.(*model.PostList); len(result.Order) != 1 {
|
if result := Client.Must(Client.SearchPosts("from: " + user1.Username)).Data.(*model.PostList); len(result.Order) != 1 {
|
||||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
}
|
}
|
||||||
|
|
||||||
// note that this includes the "User2 has joined the channel" system messages
|
|
||||||
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))
|
||||||
}
|
}
|
||||||
@@ -526,6 +537,33 @@ func TestSearchPostsFromUser(t *testing.T) {
|
|||||||
if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " in:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 1 {
|
if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " in:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 1 {
|
||||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||||
|
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||||
|
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||||
|
|
||||||
|
Client.LoginByEmail(team.Name, user3.Email, "pwd")
|
||||||
|
Client.Must(Client.JoinChannel(channel1.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 {
|
||||||
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " from: " + user3.Username)).Data.(*model.PostList); len(result.Order) != 5 {
|
||||||
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " from: " + user3.Username + " in:" + channel2.Name)).Data.(*model.PostList); len(result.Order) != 3 {
|
||||||
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " from: " + user3.Username + " in:" + channel2.Name + " joined")).Data.(*model.PostList); len(result.Order) != 2 {
|
||||||
|
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPostsCache(t *testing.T) {
|
func TestGetPostsCache(t *testing.T) {
|
||||||
|
|||||||
@@ -54,6 +54,15 @@ func (o *PostList) AddPost(post *Post) {
|
|||||||
o.Posts[post.Id] = post
|
o.Posts[post.Id] = post
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *PostList) Extend(other *PostList) {
|
||||||
|
for _, postId := range other.Order {
|
||||||
|
if _, ok := o.Posts[postId]; !ok {
|
||||||
|
o.AddPost(other.Posts[postId])
|
||||||
|
o.AddOrder(postId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (o *PostList) Etag() string {
|
func (o *PostList) Etag() string {
|
||||||
|
|
||||||
id := "0"
|
id := "0"
|
||||||
|
|||||||
@@ -34,3 +34,37 @@ func TestPostListJson(t *testing.T) {
|
|||||||
t.Fatal("failed to serialize")
|
t.Fatal("failed to serialize")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPostListExtend(t *testing.T) {
|
||||||
|
l1 := PostList{}
|
||||||
|
|
||||||
|
p1 := &Post{Id: NewId(), Message: NewId()}
|
||||||
|
l1.AddPost(p1)
|
||||||
|
l1.AddOrder(p1.Id)
|
||||||
|
|
||||||
|
p2 := &Post{Id: NewId(), Message: NewId()}
|
||||||
|
l1.AddPost(p2)
|
||||||
|
l1.AddOrder(p2.Id)
|
||||||
|
|
||||||
|
l2 := PostList{}
|
||||||
|
|
||||||
|
p3 := &Post{Id: NewId(), Message: NewId()}
|
||||||
|
l2.AddPost(p3)
|
||||||
|
l2.AddOrder(p3.Id)
|
||||||
|
|
||||||
|
l2.Extend(&l1)
|
||||||
|
|
||||||
|
if len(l1.Posts) != 2 || len(l1.Order) != 2 {
|
||||||
|
t.Fatal("extending l2 changed l1")
|
||||||
|
} else if len(l2.Posts) != 3 {
|
||||||
|
t.Fatal("failed to extend posts l2")
|
||||||
|
} else if l2.Order[0] != p3.Id || l2.Order[1] != p1.Id || l2.Order[2] != p2.Id {
|
||||||
|
t.Fatal("failed to extend order of l2")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(l1.Posts) != 2 || len(l1.Order) != 2 {
|
||||||
|
t.Fatal("extending l2 again changed l1")
|
||||||
|
} else if len(l2.Posts) != 3 || len(l2.Order) != 3 {
|
||||||
|
t.Fatal("extending l2 again changed l2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"}
|
||||||
@@ -31,9 +31,9 @@ func splitWords(text string) []string {
|
|||||||
return words
|
return words
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSearchFlags(input []string) ([]string, map[string]string) {
|
func parseSearchFlags(input []string) ([]string, [][2]string) {
|
||||||
words := []string{}
|
words := []string{}
|
||||||
flags := make(map[string]string)
|
flags := [][2]string{}
|
||||||
|
|
||||||
skipNextWord := false
|
skipNextWord := false
|
||||||
for i, word := range input {
|
for i, word := range input {
|
||||||
@@ -52,10 +52,10 @@ func parseSearchFlags(input []string) ([]string, map[string]string) {
|
|||||||
// check for case insensitive equality
|
// check for case insensitive equality
|
||||||
if strings.EqualFold(flag, searchFlag) {
|
if strings.EqualFold(flag, searchFlag) {
|
||||||
if value != "" {
|
if value != "" {
|
||||||
flags[searchFlag] = value
|
flags = append(flags, [2]string{searchFlag, value})
|
||||||
isFlag = true
|
isFlag = true
|
||||||
} else if i < len(input)-1 {
|
} else if i < len(input)-1 {
|
||||||
flags[searchFlag] = input[i+1]
|
flags = append(flags, [2]string{searchFlag, input[i+1]})
|
||||||
skipNextWord = true
|
skipNextWord = true
|
||||||
isFlag = true
|
isFlag = true
|
||||||
}
|
}
|
||||||
@@ -75,56 +75,66 @@ func parseSearchFlags(input []string) ([]string, map[string]string) {
|
|||||||
return words, flags
|
return words, flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseSearchParams(text string) (*SearchParams, *SearchParams) {
|
func ParseSearchParams(text string) []*SearchParams {
|
||||||
words, flags := parseSearchFlags(splitWords(text))
|
words, flags := parseSearchFlags(splitWords(text))
|
||||||
|
|
||||||
hashtagTerms := []string{}
|
hashtagTermList := []string{}
|
||||||
plainTerms := []string{}
|
plainTermList := []string{}
|
||||||
|
|
||||||
for _, word := range words {
|
for _, word := range words {
|
||||||
if validHashtag.MatchString(word) {
|
if validHashtag.MatchString(word) {
|
||||||
hashtagTerms = append(hashtagTerms, word)
|
hashtagTermList = append(hashtagTermList, word)
|
||||||
} else {
|
} else {
|
||||||
plainTerms = append(plainTerms, word)
|
plainTermList = append(plainTermList, word)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inChannel := flags["channel"]
|
hashtagTerms := strings.Join(hashtagTermList, " ")
|
||||||
if inChannel == "" {
|
plainTerms := strings.Join(plainTermList, " ")
|
||||||
inChannel = flags["in"]
|
|
||||||
|
inChannels := []string{}
|
||||||
|
fromUsers := []string{}
|
||||||
|
|
||||||
|
for _, flagPair := range flags {
|
||||||
|
flag := flagPair[0]
|
||||||
|
value := flagPair[1]
|
||||||
|
|
||||||
|
if flag == "in" || flag == "channel" {
|
||||||
|
inChannels = append(inChannels, value)
|
||||||
|
} else if flag == "from" {
|
||||||
|
fromUsers = append(fromUsers, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fromUser := flags["from"]
|
paramsList := []*SearchParams{}
|
||||||
|
|
||||||
var plainParams *SearchParams
|
|
||||||
if len(plainTerms) > 0 {
|
if len(plainTerms) > 0 {
|
||||||
plainParams = &SearchParams{
|
paramsList = append(paramsList, &SearchParams{
|
||||||
Terms: strings.Join(plainTerms, " "),
|
Terms: plainTerms,
|
||||||
IsHashtag: false,
|
IsHashtag: false,
|
||||||
InChannel: inChannel,
|
InChannels: inChannels,
|
||||||
FromUser: fromUser,
|
FromUsers: fromUsers,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashtagParams *SearchParams
|
|
||||||
if len(hashtagTerms) > 0 {
|
if len(hashtagTerms) > 0 {
|
||||||
hashtagParams = &SearchParams{
|
paramsList = append(paramsList, &SearchParams{
|
||||||
Terms: strings.Join(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 plainParams == nil && hashtagParams == nil && (inChannel != "" || fromUser != "") {
|
if len(plainTerms) == 0 && len(hashtagTerms) == 0 {
|
||||||
plainParams = &SearchParams{
|
paramsList = append(paramsList, &SearchParams{
|
||||||
Terms: "",
|
Terms: "",
|
||||||
IsHashtag: false,
|
IsHashtag: true,
|
||||||
InChannel: inChannel,
|
InChannels: inChannels,
|
||||||
FromUser: fromUser,
|
FromUsers: fromUsers,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return plainParams, hashtagParams
|
return paramsList
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,25 +28,25 @@ func TestParseSearchFlags(t *testing.T) {
|
|||||||
|
|
||||||
if words, flags := parseSearchFlags(splitWords("apple banana from:chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
if words, flags := parseSearchFlags(splitWords("apple banana from:chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
||||||
t.Fatalf("got incorrect words %v", words)
|
t.Fatalf("got incorrect words %v", words)
|
||||||
} else if len(flags) != 1 || flags["from"] != "chan" {
|
} else if len(flags) != 1 || flags[0][0] != "from" || flags[0][1] != "chan" {
|
||||||
t.Fatalf("got incorrect flags %v", flags)
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if words, flags := parseSearchFlags(splitWords("apple banana from: chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
if words, flags := parseSearchFlags(splitWords("apple banana from: chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
||||||
t.Fatalf("got incorrect words %v", words)
|
t.Fatalf("got incorrect words %v", words)
|
||||||
} else if len(flags) != 1 || flags["from"] != "chan" {
|
} else if len(flags) != 1 || flags[0][0] != "from" || flags[0][1] != "chan" {
|
||||||
t.Fatalf("got incorrect flags %v", flags)
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if words, flags := parseSearchFlags(splitWords("apple banana in: chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
if words, flags := parseSearchFlags(splitWords("apple banana in: chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
||||||
t.Fatalf("got incorrect words %v", words)
|
t.Fatalf("got incorrect words %v", words)
|
||||||
} else if len(flags) != 1 || flags["in"] != "chan" {
|
} else if len(flags) != 1 || flags[0][0] != "in" || flags[0][1] != "chan" {
|
||||||
t.Fatalf("got incorrect flags %v", flags)
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if words, flags := parseSearchFlags(splitWords("apple banana channel:chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
if words, flags := parseSearchFlags(splitWords("apple banana channel:chan")); len(words) != 2 || words[0] != "apple" || words[1] != "banana" {
|
||||||
t.Fatalf("got incorrect words %v", words)
|
t.Fatalf("got incorrect words %v", words)
|
||||||
} else if len(flags) != 1 || flags["channel"] != "chan" {
|
} else if len(flags) != 1 || flags[0][0] != "channel" || flags[0][1] != "chan" {
|
||||||
t.Fatalf("got incorrect flags %v", flags)
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,14 @@ func TestParseSearchFlags(t *testing.T) {
|
|||||||
|
|
||||||
if words, flags := parseSearchFlags(splitWords("channel: first in: second from:")); len(words) != 1 || words[0] != "from:" {
|
if words, flags := parseSearchFlags(splitWords("channel: first in: second from:")); len(words) != 1 || words[0] != "from:" {
|
||||||
t.Fatalf("got incorrect words %v", words)
|
t.Fatalf("got incorrect words %v", words)
|
||||||
} else if len(flags) != 2 || flags["channel"] != "first" || flags["in"] != "second" {
|
} else if len(flags) != 2 || flags[0][0] != "channel" || flags[0][1] != "first" || flags[1][0] != "in" || flags[1][1] != "second" {
|
||||||
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
if words, flags := parseSearchFlags(splitWords("channel: first channel: second from: third from: fourth")); len(words) != 0 {
|
||||||
|
t.Fatalf("got incorrect words %v", words)
|
||||||
|
} else if len(flags) != 4 || flags[0][0] != "channel" || flags[0][1] != "first" || flags[1][0] != "channel" || flags[1][1] != "second" ||
|
||||||
|
flags[2][0] != "from" || flags[2][1] != "third" || flags[3][0] != "from" || flags[3][1] != "fourth" {
|
||||||
t.Fatalf("got incorrect flags %v", flags)
|
t.Fatalf("got incorrect flags %v", flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user