summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2017-10-31 11:52:10 -0400
committerGeorge Goldberg <george@gberg.me>2017-10-31 15:52:10 +0000
commit6886de04d4215ea45ae535b64a604a79292bff77 (patch)
treeda3744dbbac2bdf3bd5986da4c59aab649570b68
parentb3b46a01aae85594b9b3d2d8872d33d6812492a6 (diff)
downloadchat-6886de04d4215ea45ae535b64a604a79292bff77.tar.gz
chat-6886de04d4215ea45ae535b64a604a79292bff77.tar.bz2
chat-6886de04d4215ea45ae535b64a604a79292bff77.zip
PLT-6071/PLT-8004 Fixed not being able to autocomplete 'Town Square' (#7746)
-rw-r--r--store/sqlstore/channel_store.go2
-rw-r--r--store/sqlstore/user_store.go53
-rw-r--r--store/storetest/channel_store.go20
3 files changed, 48 insertions, 27 deletions
diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go
index cf712d974..2654082c8 100644
--- a/store/sqlstore/channel_store.go
+++ b/store/sqlstore/channel_store.go
@@ -1263,7 +1263,7 @@ func (s SqlChannelStore) performSearch(searchQuery string, term string, paramete
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", "", 1)
} else {
isPostgreSQL := s.DriverName() == model.DATABASE_DRIVER_POSTGRES
- searchQuery = generateSearchQuery(searchQuery, term, "Name, DisplayName", parameters, isPostgreSQL)
+ searchQuery = generateSearchQuery(searchQuery, []string{term}, []string{"Name", "DisplayName"}, parameters, isPostgreSQL)
}
var channels model.ChannelList
diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go
index 3fafc7eab..09b1ce1be 100644
--- a/store/sqlstore/user_store.go
+++ b/store/sqlstore/user_store.go
@@ -17,14 +17,17 @@ import (
)
const (
- PROFILES_IN_CHANNEL_CACHE_SIZE = model.CHANNEL_CACHE_SIZE
- PROFILES_IN_CHANNEL_CACHE_SEC = 900 // 15 mins
- PROFILE_BY_IDS_CACHE_SIZE = model.SESSION_CACHE_SIZE
- PROFILE_BY_IDS_CACHE_SEC = 900 // 15 mins
- USER_SEARCH_TYPE_NAMES_NO_FULL_NAME = "Username, Nickname"
- USER_SEARCH_TYPE_NAMES = "Username, FirstName, LastName, Nickname"
- USER_SEARCH_TYPE_ALL_NO_FULL_NAME = "Username, Nickname, Email"
- USER_SEARCH_TYPE_ALL = "Username, FirstName, LastName, Nickname, Email"
+ PROFILES_IN_CHANNEL_CACHE_SIZE = model.CHANNEL_CACHE_SIZE
+ PROFILES_IN_CHANNEL_CACHE_SEC = 900 // 15 mins
+ PROFILE_BY_IDS_CACHE_SIZE = model.SESSION_CACHE_SIZE
+ PROFILE_BY_IDS_CACHE_SEC = 900 // 15 mins
+)
+
+var (
+ USER_SEARCH_TYPE_NAMES_NO_FULL_NAME = []string{"Username", "Nickname"}
+ USER_SEARCH_TYPE_NAMES = []string{"Username", "FirstName", "LastName", "Nickname"}
+ USER_SEARCH_TYPE_ALL_NO_FULL_NAME = []string{"Username", "Nickname", "Email"}
+ USER_SEARCH_TYPE_ALL = []string{"Username", "FirstName", "LastName", "Nickname", "Email"}
)
type SqlUserStore struct {
@@ -86,10 +89,10 @@ func (us SqlUserStore) CreateIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_users_lastname_lower", "Users", "lower(LastName)")
}
- us.CreateFullTextIndexIfNotExists("idx_users_all_txt", "Users", USER_SEARCH_TYPE_ALL)
- us.CreateFullTextIndexIfNotExists("idx_users_all_no_full_name_txt", "Users", USER_SEARCH_TYPE_ALL_NO_FULL_NAME)
- us.CreateFullTextIndexIfNotExists("idx_users_names_txt", "Users", USER_SEARCH_TYPE_NAMES)
- us.CreateFullTextIndexIfNotExists("idx_users_names_no_full_name_txt", "Users", USER_SEARCH_TYPE_NAMES_NO_FULL_NAME)
+ us.CreateFullTextIndexIfNotExists("idx_users_all_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL, ", "))
+ us.CreateFullTextIndexIfNotExists("idx_users_all_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL_NO_FULL_NAME, ", "))
+ us.CreateFullTextIndexIfNotExists("idx_users_names_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES, ", "))
+ us.CreateFullTextIndexIfNotExists("idx_users_names_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES_NO_FULL_NAME, ", "))
}
func (us SqlUserStore) Save(user *model.User) store.StoreChannel {
@@ -1028,25 +1031,22 @@ var ignoreUserSearchChar = []string{
"*",
}
-func generateSearchQuery(searchQuery, term, searchField string, parameters map[string]interface{}, isPostgreSQL bool) string {
- splitTerms := strings.Fields(term)
- splitFields := strings.Split(searchField, ", ")
-
- terms := []string{}
- for i, term := range splitTerms {
- fields := []string{}
- for _, field := range splitFields {
+func generateSearchQuery(searchQuery string, terms []string, fields []string, parameters map[string]interface{}, isPostgreSQL bool) string {
+ searchTerms := []string{}
+ for i, term := range terms {
+ searchFields := []string{}
+ for _, field := range fields {
if isPostgreSQL {
- fields = append(fields, fmt.Sprintf("lower(%s) LIKE lower(%s) escape '*' ", field, fmt.Sprintf(":Term%d", i)))
+ searchFields = append(searchFields, fmt.Sprintf("lower(%s) LIKE lower(%s) escape '*' ", field, fmt.Sprintf(":Term%d", i)))
} else {
- fields = append(fields, fmt.Sprintf("%s LIKE %s escape '*' ", field, fmt.Sprintf(":Term%d", i)))
+ searchFields = append(searchFields, fmt.Sprintf("%s LIKE %s escape '*' ", field, fmt.Sprintf(":Term%d", i)))
}
}
- terms = append(terms, fmt.Sprintf("(%s)", strings.Join(fields, " OR ")))
+ searchTerms = append(searchTerms, fmt.Sprintf("(%s)", strings.Join(searchFields, " OR ")))
parameters[fmt.Sprintf("Term%d", i)] = fmt.Sprintf("%s%%", term)
}
- searchClause := strings.Join(terms, " AND ")
+ searchClause := strings.Join(searchTerms, " AND ")
return strings.Replace(searchQuery, "SEARCH_CLAUSE", fmt.Sprintf(" AND %s ", searchClause), 1)
}
@@ -1082,13 +1082,14 @@ func (us SqlUserStore) performSearch(searchQuery string, term string, options ma
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", "", 1)
} else {
isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
- searchQuery = generateSearchQuery(searchQuery, term, searchType, parameters, isPostgreSQL)
+ searchQuery = generateSearchQuery(searchQuery, strings.Fields(term), searchType, parameters, isPostgreSQL)
}
var users []*model.User
if _, err := us.GetReplica().Select(&users, searchQuery, parameters); err != nil {
- result.Err = model.NewAppError("SqlUserStore.Search", "store.sql_user.search.app_error", nil, "term="+term+", "+"search_type="+searchType+", "+err.Error(), http.StatusInternalServerError)
+ result.Err = model.NewAppError("SqlUserStore.Search", "store.sql_user.search.app_error", nil,
+ fmt.Sprintf("term=%v, search_type=%v, %v", term, searchType, err.Error()), http.StatusInternalServerError)
} else {
for _, u := range users {
u.Sanitize(map[string]bool{})
diff --git a/store/storetest/channel_store.go b/store/storetest/channel_store.go
index cb4e8fa26..1189fd976 100644
--- a/store/storetest/channel_store.go
+++ b/store/storetest/channel_store.go
@@ -1861,6 +1861,13 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
o8.Type = model.CHANNEL_PRIVATE
store.Must(ss.Channel().Save(&o8, -1))
+ o9 := model.Channel{}
+ o9.TeamId = o1.TeamId
+ o9.DisplayName = "Town Square"
+ o9.Name = "town-square"
+ o9.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&o9, -1))
+
if result := <-ss.Channel().SearchInTeam(o1.TeamId, "ChannelA"); result.Err != nil {
t.Fatal(result.Err)
} else {
@@ -1926,6 +1933,19 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
t.Fatal("should be empty")
}
}
+
+ if result := <-ss.Channel().SearchInTeam(o1.TeamId, "town square"); result.Err != nil {
+ t.Fatal(result.Err)
+ } else {
+ channels := result.Data.(*model.ChannelList)
+ if len(*channels) != 1 {
+ t.Fatal("should return 1 channel")
+ }
+
+ if (*channels)[0].Name != o9.Name {
+ t.Fatal("wrong channel returned")
+ }
+ }
}
func testChannelStoreGetMembersByIds(t *testing.T, ss store.Store) {