summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2015-10-17 14:37:51 -0400
committerhmhealey <harrisonmhealey@gmail.com>2015-10-19 13:25:19 -0400
commit06fd374c1907add3faeeba7916b279e0a3302a4e (patch)
tree278094fd30b875ed431467e7505294edf1852e56
parent754f1721fe77b3f842277d1c72e25e83cf993133 (diff)
downloadchat-06fd374c1907add3faeeba7916b279e0a3302a4e.tar.gz
chat-06fd374c1907add3faeeba7916b279e0a3302a4e.tar.bz2
chat-06fd374c1907add3faeeba7916b279e0a3302a4e.zip
Added from:, in:, and channel: search modifiers
-rw-r--r--api/post.go10
-rw-r--r--api/post_test.go122
-rw-r--r--model/search_params.go130
-rw-r--r--model/search_params_test.go70
-rw-r--r--model/utils.go4
-rw-r--r--store/sql_post_store.go128
-rw-r--r--store/sql_post_store_test.go22
-rw-r--r--store/store.go2
8 files changed, 420 insertions, 68 deletions
diff --git a/api/post.go b/api/post.go
index 58fd3488a..ecc319a91 100644
--- a/api/post.go
+++ b/api/post.go
@@ -680,16 +680,16 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- hashtagTerms, plainTerms := model.ParseHashtags(terms)
+ plainSearchParams, hashtagSearchParams := model.ParseSearchParams(terms)
var hchan store.StoreChannel
- if len(hashtagTerms) != 0 {
- hchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, hashtagTerms, true)
+ if hashtagSearchParams != nil {
+ hchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, hashtagSearchParams)
}
var pchan store.StoreChannel
- if len(plainTerms) != 0 {
- pchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, terms, false)
+ if plainSearchParams != nil {
+ pchan = Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, plainSearchParams)
}
mainList := &model.PostList{}
diff --git a/api/post_test.go b/api/post_test.go
index 1971b6114..ac9d5668b 100644
--- a/api/post_test.go
+++ b/api/post_test.go
@@ -406,6 +406,128 @@ func TestSearchHashtagPosts(t *testing.T) {
}
}
+func TestSearchPostsInChannel(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user1.Id))
+
+ Client.LoginByEmail(team.Name, user1.Email, "pwd")
+
+ channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
+ channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
+
+ post1 := &model.Post{ChannelId: channel1.Id, Message: "sgtitlereview with space"}
+ post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
+
+ 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)
+
+ post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
+ post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
+
+ post3 := &model.Post{ChannelId: channel2.Id, Message: "other message with no return"}
+ post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post)
+
+ 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))
+ }
+
+ if result := Client.Must(Client.SearchPosts("in:")).Data.(*model.PostList); len(result.Order) != 0 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("channel:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 1 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("in: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 2 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("channel: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 2 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("ChAnNeL: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 2 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("sgtitlereview")).Data.(*model.PostList); len(result.Order) != 2 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("sgtitlereview in:")).Data.(*model.PostList); len(result.Order) != 2 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("sgtitlereview channel:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 1 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("sgtitlereview in: " + channel2.Name)).Data.(*model.PostList); len(result.Order) != 1 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ 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))
+ }
+}
+
+func TestSearchPostsFromUser(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user1.Id))
+
+ Client.LoginByEmail(team.Name, user1.Email, "pwd")
+
+ channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
+ channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
+
+ 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)
+
+ post1 := &model.Post{ChannelId: channel1.Id, Message: "sgtitlereview with space"}
+ post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
+
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user2.Id))
+
+ Client.LoginByEmail(team.Name, user2.Email, "pwd")
+ Client.Must(Client.JoinChannel(channel1.Id))
+ Client.Must(Client.JoinChannel(channel2.Id))
+
+ post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
+ post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
+
+ 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))
+ }
+
+ // 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 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ if result := Client.Must(Client.SearchPosts("from: " + user2.Username + " sgtitlereview")).Data.(*model.PostList); len(result.Order) != 1 {
+ t.Fatalf("wrong number of posts returned %v", len(result.Order))
+ }
+
+ 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))
+ }
+}
+
func TestGetPostsCache(t *testing.T) {
Setup()
diff --git a/model/search_params.go b/model/search_params.go
new file mode 100644
index 000000000..7eeeed10f
--- /dev/null
+++ b/model/search_params.go
@@ -0,0 +1,130 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "strings"
+)
+
+type SearchParams struct {
+ Terms string
+ IsHashtag bool
+ InChannel string
+ FromUser string
+}
+
+var searchFlags = [...]string{"from", "channel", "in"}
+
+func splitWords(text string) []string {
+ words := []string{}
+
+ for _, word := range strings.Fields(text) {
+ word = puncStart.ReplaceAllString(word, "")
+ word = puncEnd.ReplaceAllString(word, "")
+
+ if len(word) != 0 {
+ words = append(words, word)
+ }
+ }
+
+ return words
+}
+
+func parseSearchFlags(input []string) ([]string, map[string]string) {
+ words := []string{}
+ flags := make(map[string]string)
+
+ skipNextWord := false
+ for i, word := range input {
+ if skipNextWord {
+ skipNextWord = false
+ continue
+ }
+
+ isFlag := false
+
+ if colon := strings.Index(word, ":"); colon != -1 {
+ flag := word[:colon]
+ value := word[colon+1:]
+
+ for _, searchFlag := range searchFlags {
+ // check for case insensitive equality
+ if strings.EqualFold(flag, searchFlag) {
+ if value != "" {
+ flags[searchFlag] = value
+ isFlag = true
+ } else if i < len(input)-1 {
+ flags[searchFlag] = input[i+1]
+ skipNextWord = true
+ isFlag = true
+ }
+
+ if isFlag {
+ break
+ }
+ }
+ }
+ }
+
+ if !isFlag {
+ words = append(words, word)
+ }
+ }
+
+ return words, flags
+}
+
+func ParseSearchParams(text string) (*SearchParams, *SearchParams) {
+ words, flags := parseSearchFlags(splitWords(text))
+
+ hashtagTerms := []string{}
+ plainTerms := []string{}
+
+ for _, word := range words {
+ if validHashtag.MatchString(word) {
+ hashtagTerms = append(hashtagTerms, word)
+ } else {
+ plainTerms = append(plainTerms, word)
+ }
+ }
+
+ inChannel := flags["channel"]
+ if inChannel == "" {
+ inChannel = flags["in"]
+ }
+
+ fromUser := flags["from"]
+
+ var plainParams *SearchParams
+ if len(plainTerms) > 0 {
+ plainParams = &SearchParams{
+ Terms: strings.Join(plainTerms, " "),
+ IsHashtag: false,
+ InChannel: inChannel,
+ FromUser: fromUser,
+ }
+ }
+
+ var hashtagParams *SearchParams
+ if len(hashtagTerms) > 0 {
+ hashtagParams = &SearchParams{
+ Terms: strings.Join(hashtagTerms, " "),
+ IsHashtag: true,
+ InChannel: inChannel,
+ FromUser: fromUser,
+ }
+ }
+
+ // special case for when no terms are specified but we still have a filter
+ if plainParams == nil && hashtagParams == nil && (inChannel != "" || fromUser != "") {
+ plainParams = &SearchParams{
+ Terms: "",
+ IsHashtag: false,
+ InChannel: inChannel,
+ FromUser: fromUser,
+ }
+ }
+
+ return plainParams, hashtagParams
+}
diff --git a/model/search_params_test.go b/model/search_params_test.go
new file mode 100644
index 000000000..2eba20f4c
--- /dev/null
+++ b/model/search_params_test.go
@@ -0,0 +1,70 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "testing"
+)
+
+func TestParseSearchFlags(t *testing.T) {
+ if words, flags := parseSearchFlags(splitWords("")); len(words) != 0 {
+ t.Fatal("got words from empty input")
+ } else if len(flags) != 0 {
+ t.Fatal("got flags from empty input")
+ }
+
+ if words, flags := parseSearchFlags(splitWords("word")); len(words) != 1 || words[0] != "word" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 0 {
+ t.Fatalf("got incorrect flags %v", flags)
+ }
+
+ if words, flags := parseSearchFlags(splitWords("apple banana cherry")); len(words) != 3 || words[0] != "apple" || words[1] != "banana" || words[2] != "cherry" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 0 {
+ 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" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 1 || flags["from"] != "chan" {
+ 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" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 1 || flags["from"] != "chan" {
+ 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" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 1 || flags["in"] != "chan" {
+ 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" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 1 || flags["channel"] != "chan" {
+ t.Fatalf("got incorrect flags %v", flags)
+ }
+
+ if words, flags := parseSearchFlags(splitWords("fruit: cherry")); len(words) != 2 || words[0] != "fruit:" || words[1] != "cherry" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 0 {
+ t.Fatalf("got incorrect flags %v", flags)
+ }
+
+ if words, flags := parseSearchFlags(splitWords("channel:")); len(words) != 1 || words[0] != "channel:" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 0 {
+ t.Fatalf("got incorrect flags %v", flags)
+ }
+
+ if words, flags := parseSearchFlags(splitWords("channel: first in: second from:")); len(words) != 1 || words[0] != "from:" {
+ t.Fatalf("got incorrect words %v", words)
+ } else if len(flags) != 2 || flags["channel"] != "first" || flags["in"] != "second" {
+ t.Fatalf("got incorrect flags %v", flags)
+ }
+}
diff --git a/model/utils.go b/model/utils.go
index 269144afc..bb0669df7 100644
--- a/model/utils.go
+++ b/model/utils.go
@@ -242,10 +242,10 @@ func Etag(parts ...interface{}) string {
var validHashtag = regexp.MustCompile(`^(#[A-Za-z]+[A-Za-z0-9_\-]*[A-Za-z0-9])$`)
var puncStart = regexp.MustCompile(`^[.,()&$!\[\]{}"':;\\]+`)
-var puncEnd = regexp.MustCompile(`[.,()&$#!\[\]{}"':;\\]+$`)
+var puncEnd = regexp.MustCompile(`[.,()&$#!\[\]{}"';\\]+$`)
func ParseHashtags(text string) (string, string) {
- words := strings.Split(strings.Replace(text, "\n", " ", -1), " ")
+ words := strings.Fields(text)
hashtagString := ""
plainString := ""
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index 07077bd64..dc1b78ea9 100644
--- a/store/sql_post_store.go
+++ b/store/sql_post_store.go
@@ -407,15 +407,23 @@ var specialSearchChar = []string{
"@",
}
-func (s SqlPostStore) Search(teamId string, userId string, terms string, isHashtagSearch bool) StoreChannel {
+func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchParams) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
+
termMap := map[string]bool{}
+ terms := params.Terms
+
+ if terms == "" && params.InChannel == "" && params.FromUser == "" {
+ result.Data = []*model.Post{}
+ storeChannel <- result
+ return
+ }
searchType := "Message"
- if isHashtagSearch {
+ if params.IsHashtag {
searchType = "Hashtags"
for _, term := range strings.Split(terms, " ") {
termMap[term] = true
@@ -430,63 +438,85 @@ func (s SqlPostStore) Search(teamId string, userId string, terms string, isHasht
var posts []*model.Post
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
-
// Parse text for wildcards
if wildcard, err := regexp.Compile("\\*($| )"); err == nil {
terms = wildcard.ReplaceAllLiteralString(terms, ":* ")
}
+ }
- 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 @@ to_tsquery($3)
- ORDER BY CreateAt DESC
- LIMIT 100`, searchType)
-
- terms = strings.Join(strings.Fields(terms), " | ")
+ searchQuery := `
+ SELECT
+ *
+ FROM
+ Posts
+ WHERE
+ DeleteAt = 0
+ POST_FILTER
+ AND ChannelId IN (
+ SELECT
+ Id
+ FROM
+ Channels,
+ ChannelMembers
+ WHERE
+ Id = ChannelId
+ AND TeamId = :TeamId
+ AND UserId = :UserId
+ AND DeleteAt = 0
+ CHANNEL_FILTER)
+ SEARCH_CLAUSE
+ ORDER BY CreateAt DESC
+ LIMIT 100`
+
+ if params.InChannel != "" {
+ searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "AND Name = :InChannel", 1)
+ } else {
+ searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "", 1)
+ }
- _, 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())
+ if params.FromUser != "" {
+ searchQuery = strings.Replace(searchQuery, "POST_FILTER", `
+ AND UserId IN (
+ SELECT
+ Id
+ FROM
+ Users
+ WHERE
+ TeamId = :TeamId
+ AND Username = :FromUser)`, 1)
+ } else {
+ searchQuery = strings.Replace(searchQuery, "POST_FILTER", "", 1)
+ }
+ if terms == "" {
+ // we've already confirmed that we have a channel or user to search for
+ searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", "", 1)
+ } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
+ // Parse text for wildcards
+ if wildcard, err := regexp.Compile("\\*($| )"); err == nil {
+ terms = wildcard.ReplaceAllLiteralString(terms, ":* ")
}
+
+ terms = strings.Join(strings.Fields(terms), " | ")
+
+ searchClause := fmt.Sprintf("AND %s @@ to_tsquery(:Terms)", searchType)
+ searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1)
} else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
- searchQuery := fmt.Sprintf(`SELECT
- *
- FROM
- Posts
- WHERE
- DeleteAt = 0
- AND ChannelId IN (SELECT
- Id
- FROM
- Channels,
- ChannelMembers
- WHERE
- Id = ChannelId AND TeamId = ?
- AND UserId = ?
- AND DeleteAt = 0)
- AND MATCH (%s) AGAINST (? IN BOOLEAN MODE)
- ORDER BY CreateAt DESC
- LIMIT 100`, searchType)
-
- _, 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())
+ searchClause := fmt.Sprintf("AND MATCH (%s) AGAINST (:Terms IN BOOLEAN MODE)", searchType)
+ searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1)
+ }
- }
+ queryParams := map[string]interface{}{
+ "TeamId": teamId,
+ "UserId": userId,
+ "Terms": terms,
+ "InChannel": params.InChannel,
+ "FromUser": params.FromUser,
+ }
+
+ _, err := s.GetReplica().Select(&posts, searchQuery, queryParams)
+ 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))}
diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go
index 9a7679454..b2256417e 100644
--- a/store/sql_post_store_test.go
+++ b/store/sql_post_store_test.go
@@ -525,57 +525,57 @@ func TestPostStoreSearch(t *testing.T) {
o5.Hashtags = "#secret #howdy"
o5 = (<-store.Post().Save(o5)).Data.(*model.Post)
- r1 := (<-store.Post().Search(teamId, userId, "corey", false)).Data.(*model.PostList)
+ r1 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "corey", IsHashtag: false})).Data.(*model.PostList)
if len(r1.Order) != 1 && r1.Order[0] != o1.Id {
t.Fatal("returned wrong search result")
}
- r3 := (<-store.Post().Search(teamId, userId, "new", false)).Data.(*model.PostList)
+ r3 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "new", IsHashtag: false})).Data.(*model.PostList)
if len(r3.Order) != 2 && r3.Order[0] != o1.Id {
t.Fatal("returned wrong search result")
}
- r4 := (<-store.Post().Search(teamId, userId, "john", false)).Data.(*model.PostList)
+ r4 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "john", IsHashtag: false})).Data.(*model.PostList)
if len(r4.Order) != 1 && r4.Order[0] != o2.Id {
t.Fatal("returned wrong search result")
}
- r5 := (<-store.Post().Search(teamId, userId, "matter*", false)).Data.(*model.PostList)
+ r5 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter*", IsHashtag: false})).Data.(*model.PostList)
if len(r5.Order) != 1 && r5.Order[0] != o1.Id {
t.Fatal("returned wrong search result")
}
- r6 := (<-store.Post().Search(teamId, userId, "#hashtag", true)).Data.(*model.PostList)
+ r6 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "#hashtag", IsHashtag: true})).Data.(*model.PostList)
if len(r6.Order) != 1 && r6.Order[0] != o4.Id {
t.Fatal("returned wrong search result")
}
- r7 := (<-store.Post().Search(teamId, userId, "#secret", true)).Data.(*model.PostList)
+ r7 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "#secret", IsHashtag: true})).Data.(*model.PostList)
if len(r7.Order) != 1 && r7.Order[0] != o5.Id {
t.Fatal("returned wrong search result")
}
- r8 := (<-store.Post().Search(teamId, userId, "@thisshouldmatchnothing", true)).Data.(*model.PostList)
+ r8 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "@thisshouldmatchnothing", IsHashtag: true})).Data.(*model.PostList)
if len(r8.Order) != 0 {
t.Fatal("returned wrong search result")
}
- r9 := (<-store.Post().Search(teamId, userId, "mattermost jersey", false)).Data.(*model.PostList)
+ r9 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "mattermost jersey", IsHashtag: false})).Data.(*model.PostList)
if len(r9.Order) != 2 {
t.Fatal("returned wrong search result")
}
- r10 := (<-store.Post().Search(teamId, userId, "matter* jer*", false)).Data.(*model.PostList)
+ r10 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter* jer*", IsHashtag: false})).Data.(*model.PostList)
if len(r10.Order) != 2 {
t.Fatal("returned wrong search result")
}
- r11 := (<-store.Post().Search(teamId, userId, "message blargh", false)).Data.(*model.PostList)
+ r11 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "message blargh", IsHashtag: false})).Data.(*model.PostList)
if len(r11.Order) != 1 {
t.Fatal("returned wrong search result")
}
- r12 := (<-store.Post().Search(teamId, userId, "blargh>", false)).Data.(*model.PostList)
+ r12 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "blargh>", IsHashtag: false})).Data.(*model.PostList)
if len(r12.Order) != 1 {
t.Fatal("returned wrong search result")
}
diff --git a/store/store.go b/store/store.go
index de335cc2b..7f31325fd 100644
--- a/store/store.go
+++ b/store/store.go
@@ -84,7 +84,7 @@ type PostStore interface {
GetPosts(channelId string, offset int, limit int) StoreChannel
GetPostsSince(channelId string, time int64) StoreChannel
GetEtag(channelId string) StoreChannel
- Search(teamId string, userId string, terms string, isHashtagSearch bool) StoreChannel
+ Search(teamId string, userId string, params *model.SearchParams) StoreChannel
GetForExport(channelId string) StoreChannel
}