summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2015-10-20 08:00:21 -0400
committerJoram Wilander <jwawilander@gmail.com>2015-10-20 08:00:21 -0400
commit460a82878a93ef040d2c9a1221992ed7aa808d86 (patch)
tree1a50fabf167714d614d58b1625813b34686d5fd5 /store
parent7d8e08ccf6211d3df78eb6cfd4a198df77072540 (diff)
parent995c5a276bb27f50332047684b4d8f4cfc02243b (diff)
downloadchat-460a82878a93ef040d2c9a1221992ed7aa808d86.tar.gz
chat-460a82878a93ef040d2c9a1221992ed7aa808d86.tar.bz2
chat-460a82878a93ef040d2c9a1221992ed7aa808d86.zip
Merge pull request #1113 from hmhealey/plt716
PLT-716/717 Added from:, in:, and channel: search filters
Diffstat (limited to 'store')
-rw-r--r--store/sql_post_store.go128
-rw-r--r--store/sql_post_store_test.go22
-rw-r--r--store/store.go2
3 files changed, 91 insertions, 61 deletions
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index 07077bd64..6971de9d7 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 := `
+ 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)
+ }
+
+ 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, ":* ")
}
- 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), " | ")
- _, 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 %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 70980a15c..27731cee1 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
}