[MM-13500] Adds channel /search_group endpoint (#10805)
* [MM-13500] Adds channel /search_group endpoint * Add LIMIT to the queries * Fix i18n extract * Fix tests * Add a new endpoint to get profiles by group channel ids * Rebase fix
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
604e247135
Коммит
9e9b008f3d
@@ -1473,7 +1473,7 @@ func (s SqlChannelStore) GetMemberForPost(postId string, userId string) (*model.
|
||||
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||
WHERE
|
||||
ChannelMembers.UserId = :UserId
|
||||
AND
|
||||
AND
|
||||
Posts.Id = :PostId`
|
||||
if err := s.GetReplica().SelectOne(&dbMember, query, map[string]interface{}{"UserId": userId, "PostId": postId}); err != nil {
|
||||
return nil, model.NewAppError("SqlChannelStore.GetMemberForPost", "store.sql_channel.get_member_for_post.app_error", nil, "postId="+postId+", err="+err.Error(), http.StatusInternalServerError)
|
||||
@@ -2237,6 +2237,104 @@ func (s SqlChannelStore) performSearch(searchQuery string, term string, paramete
|
||||
return &channels, nil
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) getSearchGroupChannelsQuery(userId, term string, isPostgreSQL bool) (string, map[string]interface{}) {
|
||||
var query, baseLikeClause string
|
||||
if isPostgreSQL {
|
||||
baseLikeClause = "ARRAY_TO_STRING(ARRAY_AGG(u.Username), ', ') LIKE %s"
|
||||
query = `
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
Channels
|
||||
WHERE
|
||||
Id IN (
|
||||
SELECT
|
||||
cc.Id
|
||||
FROM (
|
||||
SELECT
|
||||
c.Id
|
||||
FROM
|
||||
Channels c
|
||||
JOIN
|
||||
ChannelMembers cm on c.Id = cm.ChannelId
|
||||
JOIN
|
||||
Users u on u.Id = cm.UserId
|
||||
WHERE
|
||||
c.Type = 'G'
|
||||
AND
|
||||
u.Id = :UserId
|
||||
GROUP BY
|
||||
c.Id
|
||||
) cc
|
||||
JOIN
|
||||
ChannelMembers cm on cc.Id = cm.ChannelId
|
||||
JOIN
|
||||
Users u on u.Id = cm.UserId
|
||||
GROUP BY
|
||||
cc.Id
|
||||
HAVING
|
||||
%s
|
||||
LIMIT
|
||||
` + strconv.Itoa(model.CHANNEL_SEARCH_DEFAULT_LIMIT) + `
|
||||
)`
|
||||
} else {
|
||||
baseLikeClause = "GROUP_CONCAT(u.Username SEPARATOR ', ') LIKE %s"
|
||||
query = `
|
||||
SELECT
|
||||
cc.*
|
||||
FROM (
|
||||
SELECT
|
||||
c.*
|
||||
FROM
|
||||
Channels c
|
||||
JOIN
|
||||
ChannelMembers cm on c.Id = cm.ChannelId
|
||||
JOIN
|
||||
Users u on u.Id = cm.UserId
|
||||
WHERE
|
||||
c.Type = 'G'
|
||||
AND
|
||||
u.Id = :UserId
|
||||
GROUP BY
|
||||
c.Id
|
||||
) cc
|
||||
JOIN
|
||||
ChannelMembers cm on cc.Id = cm.ChannelId
|
||||
JOIN
|
||||
Users u on u.Id = cm.UserId
|
||||
GROUP BY
|
||||
cc.Id
|
||||
HAVING
|
||||
%s
|
||||
LIMIT
|
||||
` + strconv.Itoa(model.CHANNEL_SEARCH_DEFAULT_LIMIT)
|
||||
}
|
||||
|
||||
var likeClauses []string
|
||||
args := map[string]interface{}{"UserId": userId}
|
||||
terms := strings.Split(strings.ToLower(strings.Trim(term, " ")), " ")
|
||||
|
||||
for idx, term := range terms {
|
||||
argName := fmt.Sprintf("Term%v", idx)
|
||||
likeClauses = append(likeClauses, fmt.Sprintf(baseLikeClause, ":"+argName))
|
||||
args[argName] = "%" + term + "%"
|
||||
}
|
||||
|
||||
query = fmt.Sprintf(query, strings.Join(likeClauses, " AND "))
|
||||
return query, args
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) SearchGroupChannels(userId, term string) (*model.ChannelList, *model.AppError) {
|
||||
isPostgreSQL := s.DriverName() == model.DATABASE_DRIVER_POSTGRES
|
||||
queryString, args := s.getSearchGroupChannelsQuery(userId, term, isPostgreSQL)
|
||||
|
||||
var groupChannels model.ChannelList
|
||||
if _, err := s.GetReplica().Select(&groupChannels, queryString, args); err != nil {
|
||||
return nil, model.NewAppError("SqlChannelStore.SearchGroupChannels", "store.sql_channel.search_group_channels.app_error", nil, "userId="+userId+", term="+term+", err="+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return &groupChannels, nil
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) GetMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) {
|
||||
var dbMembers channelMemberWithSchemeRolesList
|
||||
props := make(map[string]interface{})
|
||||
|
||||
@@ -20,10 +20,11 @@ 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
|
||||
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
|
||||
MAX_GROUP_CHANNELS_FOR_PROFILES = 50
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -920,6 +921,60 @@ func (us SqlUserStore) GetProfileByIds(userIds []string, allowFromCache bool, vi
|
||||
})
|
||||
}
|
||||
|
||||
type UserWithChannel struct {
|
||||
model.User
|
||||
ChannelId string
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channelIds []string) (map[string][]*model.User, *model.AppError) {
|
||||
if len(channelIds) > MAX_GROUP_CHANNELS_FOR_PROFILES {
|
||||
channelIds = channelIds[0:MAX_GROUP_CHANNELS_FOR_PROFILES]
|
||||
}
|
||||
|
||||
isMemberQuery := fmt.Sprintf(`
|
||||
EXISTS(
|
||||
SELECT
|
||||
1
|
||||
FROM
|
||||
ChannelMembers
|
||||
WHERE
|
||||
UserId = '%s'
|
||||
AND
|
||||
ChannelId = cm.ChannelId
|
||||
)`, userId)
|
||||
|
||||
query := us.getQueryBuilder().
|
||||
Select("u.*, cm.ChannelId").
|
||||
From("Users u").
|
||||
Join("ChannelMembers cm ON u.Id = cm.UserId").
|
||||
Join("Channels c ON cm.ChannelId = c.Id").
|
||||
Where(sq.Eq{"c.Type": model.CHANNEL_GROUP, "cm.ChannelId": channelIds}).
|
||||
Where(isMemberQuery).
|
||||
Where(sq.NotEq{"u.Id": userId}).
|
||||
OrderBy("u.Username ASC")
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("SqlUserStore.GetProfileByGroupChannelIdsForUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
usersWithChannel := []*UserWithChannel{}
|
||||
if _, err := us.GetReplica().Select(&usersWithChannel, queryString, args...); err != nil {
|
||||
return nil, model.NewAppError("SqlUserStore.GetProfileByGroupChannelIdsForUser", "store.sql_user.get_profile_by_group_channel_ids_for_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
usersByChannelId := map[string][]*model.User{}
|
||||
for _, user := range usersWithChannel {
|
||||
if val, ok := usersByChannelId[user.ChannelId]; ok {
|
||||
usersByChannelId[user.ChannelId] = append(val, &user.User)
|
||||
} else {
|
||||
usersByChannelId[user.ChannelId] = []*model.User{&user.User}
|
||||
}
|
||||
}
|
||||
|
||||
return usersByChannelId, nil
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetSystemAdminProfiles() store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
|
||||
Ссылка в новой задаче
Block a user