s/u./Users./ (#29817)

Within the Users and Groups store, converge on just naming the `Users`
table instead of sometimes aliasing it and sometimes not. This makes an
informal, but unambiguous interface when sharing logic between stores,
and simplifies the next step of refactoring away from `Users.*` queries.

Relates-to: MM-62158
This commit is contained in:
Jesse Hallam 2025-01-15 06:32:17 -08:00 committed by GitHub
parent 326804ba44
commit c3ff2c5129
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 199 additions and 155 deletions

View file

@ -464,11 +464,11 @@ func (s *SqlGroupStore) GetMemberUsersSortedPage(groupID string, page int, perPa
groupMembers := []*model.User{}
userQuery := s.getQueryBuilder().
Select(`u.*`).
Select(`Users.*`).
From("GroupMembers").
Join("Users u ON u.Id = GroupMembers.UserId").
Join("Users ON Users.Id = GroupMembers.UserId").
Where(sq.Eq{"GroupMembers.DeleteAt": 0}).
Where(sq.Eq{"u.DeleteAt": 0}).
Where(sq.Eq{"Users.DeleteAt": 0}).
Where(sq.Eq{"GroupId": groupID})
userQuery = applyViewRestrictionsFilter(userQuery, viewRestrictions, true)
@ -478,28 +478,28 @@ func (s *SqlGroupStore) GetMemberUsersSortedPage(groupID string, page int, perPa
}
orderQuery := s.getQueryBuilder().
Select("u.*").
From("(" + queryString + ") AS u")
Select("Users.*").
From("(" + queryString + ") AS Users")
if teammateNameDisplay == model.ShowNicknameFullName {
orderQuery = orderQuery.OrderBy(`
CASE
WHEN u.Nickname != '' THEN u.Nickname
WHEN u.FirstName != '' AND u.LastName != '' THEN CONCAT(u.FirstName, ' ', u.LastName)
WHEN u.FirstName != '' THEN u.FirstName
WHEN u.LastName != '' THEN u.LastName
ELSE u.Username
WHEN Users.Nickname != '' THEN Users.Nickname
WHEN Users.FirstName != '' AND Users.LastName != '' THEN CONCAT(Users.FirstName, ' ', Users.LastName)
WHEN Users.FirstName != '' THEN Users.FirstName
WHEN Users.LastName != '' THEN Users.LastName
ELSE Users.Username
END`)
} else if teammateNameDisplay == model.ShowFullName {
orderQuery = orderQuery.OrderBy(`
CASE
WHEN u.FirstName != '' AND u.LastName != '' THEN CONCAT(u.FirstName, ' ', u.LastName)
WHEN u.FirstName != '' THEN u.FirstName
WHEN u.LastName != '' THEN u.LastName
ELSE u.Username
WHEN Users.FirstName != '' AND Users.LastName != '' THEN CONCAT(Users.FirstName, ' ', Users.LastName)
WHEN Users.FirstName != '' THEN Users.FirstName
WHEN Users.LastName != '' THEN Users.LastName
ELSE Users.Username
END`)
} else {
orderQuery = orderQuery.OrderBy("u.Username")
orderQuery = orderQuery.OrderBy("Users.Username")
}
orderQuery = orderQuery.
@ -531,14 +531,14 @@ func (s *SqlGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage
}
builder = s.getQueryBuilder().
Select("u.*").
From("Users u").
LeftJoin("GroupMembers ON (GroupMembers.UserId = u.Id AND GroupMembers.GroupId = ?)", groupID).
Where(sq.Eq{"u.DeleteAt": 0}).
Select("Users.*").
From("Users").
LeftJoin("GroupMembers ON (GroupMembers.UserId = Users.Id AND GroupMembers.GroupId = ?)", groupID).
Where(sq.Eq{"Users.DeleteAt": 0}).
Where("(GroupMembers.UserID IS NULL OR GroupMembers.DeleteAt != 0)").
Limit(uint64(perPage)).
Offset(uint64(page * perPage)).
OrderBy("u.Username ASC")
OrderBy("Users.Username ASC")
builder = applyViewRestrictionsFilter(builder, viewRestrictions, true)
@ -555,11 +555,11 @@ func (s *SqlGroupStore) GetMemberCount(groupID string) (int64, error) {
func (s *SqlGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
query := s.getQueryBuilder().
Select("COUNT(DISTINCT u.Id)").
Select("COUNT(DISTINCT Users.Id)").
From("GroupMembers").
Join("Users u ON u.Id = GroupMembers.UserId").
Join("Users ON Users.Id = GroupMembers.UserId").
Where(sq.Eq{"GroupMembers.GroupId": groupID}).
Where(sq.Eq{"u.DeleteAt": 0}).
Where(sq.Eq{"Users.DeleteAt": 0}).
Where(sq.Eq{"GroupMembers.DeleteAt": 0})
query = applyViewRestrictionsFilter(query, viewRestrictions, false)
@ -1456,11 +1456,11 @@ func (s *SqlGroupStore) GetGroups(page, perPage int, opts model.GroupSearchOpts,
if opts.IncludeMemberCount {
countQuery := s.getQueryBuilder().
Select("GroupMembers.GroupId, COUNT(DISTINCT u.Id) AS MemberCount").
Select("GroupMembers.GroupId, COUNT(DISTINCT Users.Id) AS MemberCount").
From("GroupMembers").
LeftJoin("Users u ON u.Id = GroupMembers.UserId").
LeftJoin("Users ON Users.Id = GroupMembers.UserId").
Where(sq.Eq{"GroupMembers.DeleteAt": 0}).
Where(sq.Eq{"u.DeleteAt": 0}).
Where(sq.Eq{"Users.DeleteAt": 0}).
GroupBy("GroupId")
countQuery = applyViewRestrictionsFilter(countQuery, viewRestrictions, false)

View file

@ -48,18 +48,64 @@ func (us *SqlUserStore) ClearCaches() {}
func (us SqlUserStore) InvalidateProfileCacheForUser(userId string) {}
// getUsersColumns exposes the set of columns that can be queried from the
// Users table (and not the Bots table).
//
// This is primarily useful for other stores who choose to directly query
// and return [model.User] data.
//
// Note that the order of these columns must match the order in
// [SqlUserStore.Get] and [SqlUserStore.GetAllProfilesInChannel].
func getUsersColumns() []string {
return []string{
"Users.Id",
"Users.CreateAt",
"Users.UpdateAt",
"Users.DeleteAt",
"Users.Username",
"Users.Password",
"Users.AuthData",
"Users.AuthService",
"Users.Email",
"Users.EmailVerified",
"Users.Nickname",
"Users.FirstName",
"Users.LastName",
"Users.Position",
"Users.Roles",
"Users.AllowMarketing",
"Users.Props",
"Users.NotifyProps",
"Users.LastPasswordUpdate",
"Users.LastPictureUpdate",
"Users.FailedAttempts",
"Users.Locale",
"Users.Timezone",
"Users.MfaActive",
"Users.MfaSecret",
"Users.MfaUsedTimestamps",
"Users.RemoteId",
"Users.LastLogin",
}
}
func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) store.UserStore {
us := &SqlUserStore{
SqlStore: sqlStore,
metrics: metrics,
}
// note: we are providing field names explicitly here to maintain order of columns (needed when using raw queries)
us.usersQuery = us.getQueryBuilder().
Select("u.Id", "u.CreateAt", "u.UpdateAt", "u.DeleteAt", "u.Username", "u.Password", "u.AuthData", "u.AuthService", "u.Email", "u.EmailVerified", "u.Nickname", "u.FirstName", "u.LastName", "u.Position", "u.Roles", "u.AllowMarketing", "u.Props", "u.NotifyProps", "u.LastPasswordUpdate", "u.LastPictureUpdate", "u.FailedAttempts", "u.Locale", "u.Timezone", "u.MfaActive", "u.MfaSecret", "u.MfaUsedTimestamps",
"b.UserId IS NOT NULL AS IsBot", "COALESCE(b.Description, '') AS BotDescription", "COALESCE(b.LastIconUpdate, 0) AS BotLastIconUpdate", "u.RemoteId", "u.LastLogin").
From("Users u").
LeftJoin("Bots b ON ( b.UserId = u.Id )")
// Together with getUsersColumns, the order specified here must match
// with [SqlUserStore.Get] and [SqlUserStore.GetAllProfilesInChannel].
Select(getUsersColumns()...).
Columns(
"b.UserId IS NOT NULL AS IsBot",
"COALESCE(b.Description, '') AS BotDescription",
"COALESCE(b.LastIconUpdate, 0) AS BotLastIconUpdate",
).
From("Users").
LeftJoin("Bots b ON ( b.UserId = Users.Id )")
return us
}
@ -477,7 +523,7 @@ func (us SqlUserStore) Get(ctx context.Context, id string) (*model.User, error)
&user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles,
&user.AllowMarketing, &props, &notifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate,
&user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps,
&user.IsBot, &user.BotDescription, &user.BotLastIconUpdate, &user.RemoteId, &user.LastLogin)
&user.RemoteId, &user.LastLogin, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate)
if err != nil {
if err == sql.ErrNoRows {
return nil, store.NewErrNotFound("User", id)
@ -538,7 +584,7 @@ func (us SqlUserStore) GetEtagForAllProfiles() string {
func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.User, error) {
isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres
query := us.usersQuery.
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
@ -547,9 +593,9 @@ func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.U
query = applyMultiRoleFilters(query, options.Roles, []string{}, []string{}, isPostgreSQL)
if options.Inactive {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
users := []*model.User{}
@ -571,12 +617,12 @@ func applyRoleFilter(query sq.SelectBuilder, role string, isPostgreSQL bool) sq.
if isPostgreSQL {
roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "\\"))
return query.Where("u.Roles LIKE LOWER(?)", roleParam)
return query.Where("Users.Roles LIKE LOWER(?)", roleParam)
}
roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "*"))
return query.Where("u.Roles LIKE ? ESCAPE '*'", roleParam)
return query.Where("Users.Roles LIKE ? ESCAPE '*'", roleParam)
}
func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRoles []string, channelRoles []string, isPostgreSQL bool) sq.SelectBuilder {
@ -588,13 +634,13 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol
switch role {
case model.SystemUserRoleId:
// If querying for a `system_user` ensure that the user is only a system_user.
sqOr = append(sqOr, sq.Eq{"u.Roles": role})
sqOr = append(sqOr, sq.Eq{"Users.Roles": role})
case model.SystemGuestRoleId, model.SystemAdminRoleId, model.SystemUserManagerRoleId, model.SystemReadOnlyAdminRoleId, model.SystemManagerRoleId:
// If querying for any other roles search using a wildcard.
if isPostgreSQL {
sqOr = append(sqOr, sq.ILike{"u.Roles": queryRole})
sqOr = append(sqOr, sq.ILike{"Users.Roles": queryRole})
} else {
sqOr = append(sqOr, sq.Like{"u.Roles": queryRole})
sqOr = append(sqOr, sq.Like{"Users.Roles": queryRole})
}
}
}
@ -605,15 +651,15 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol
switch channelRole {
case model.ChannelAdminRoleId:
if isPostgreSQL {
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
} else {
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
}
case model.ChannelUserRoleId:
if isPostgreSQL {
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
} else {
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
}
case model.ChannelGuestRoleId:
sqOr = append(sqOr, sq.Eq{"cm.SchemeGuest": true})
@ -626,15 +672,15 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol
switch teamRole {
case model.TeamAdminRoleId:
if isPostgreSQL {
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
} else {
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
}
case model.TeamUserRoleId:
if isPostgreSQL {
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
} else {
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}})
}
case model.TeamGuestRoleId:
sqOr = append(sqOr, sq.Eq{"tm.SchemeGuest": true})
@ -654,7 +700,7 @@ func applyChannelGroupConstrainedFilter(query sq.SelectBuilder, channelId string
}
return query.
Where(`u.Id IN (
Where(`Users.Id IN (
SELECT
GroupMembers.UserId
FROM
@ -678,7 +724,7 @@ func applyTeamGroupConstrainedFilter(query sq.SelectBuilder, teamId string) sq.S
}
return query.
Where(`u.Id IN (
Where(`Users.Id IN (
SELECT
GroupMembers.UserId
FROM
@ -708,9 +754,9 @@ func (us SqlUserStore) GetEtagForProfiles(teamId string) string {
func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User, error) {
isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres
query := us.usersQuery.
Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 )").
Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 )").
Where("tm.TeamId = ?", options.InTeamId).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
@ -719,9 +765,9 @@ func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User
query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL)
if options.Inactive {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
users := []*model.User{}
@ -742,15 +788,15 @@ func (us SqlUserStore) InvalidateProfilesInChannelCache(channelId string) {}
func (us SqlUserStore) GetProfilesInChannel(options *model.UserGetOptions) ([]*model.User, error) {
query := us.usersQuery.
Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
Join("ChannelMembers cm ON ( cm.UserId = Users.Id )").
Where("cm.ChannelId = ?", options.InChannelId).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
if options.Inactive {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, us.DriverName() == model.DatabaseDriverPostgres)
@ -769,8 +815,8 @@ func (us SqlUserStore) GetProfilesInChannel(options *model.UserGetOptions) ([]*m
func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOptions) ([]*model.User, error) {
query := us.usersQuery.
Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
LeftJoin("Status s ON ( s.UserId = u.Id )").
Join("ChannelMembers cm ON ( cm.UserId = Users.Id )").
LeftJoin("Status s ON ( s.UserId = Users.Id )").
Where("cm.ChannelId = ?", options.InChannelId).
OrderBy(`
CASE s.Status
@ -780,13 +826,13 @@ func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOption
ELSE 4
END
`).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
if options.Inactive && !options.Active {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active && !options.Inactive {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
users := []*model.User{}
@ -803,16 +849,16 @@ func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOption
func (us SqlUserStore) GetProfilesInChannelByAdmin(options *model.UserGetOptions) ([]*model.User, error) {
query := us.usersQuery.
Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
Join("ChannelMembers cm ON ( cm.UserId = Users.Id )").
Where("cm.ChannelId = ?", options.InChannelId).
OrderBy(`cm.SchemeAdmin DESC`).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
if options.Inactive && !options.Active {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active && !options.Inactive {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
queryString, args, err := query.ToSql()
@ -834,10 +880,10 @@ func (us SqlUserStore) GetProfilesInChannelByAdmin(options *model.UserGetOptions
func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID string, allowFromCache bool) (map[string]*model.User, error) {
query := us.usersQuery.
Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
Join("ChannelMembers cm ON ( cm.UserId = Users.Id )").
Where("cm.ChannelId = ?", channelID).
Where("u.DeleteAt = 0").
OrderBy("u.Username ASC")
Where("Users.DeleteAt = 0").
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -854,7 +900,7 @@ func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID st
for rows.Next() {
var user model.User
var props, notifyProps, timezone []byte
if err = rows.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username, &user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified, &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, &notifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate, &user.RemoteId, &user.LastLogin); err != nil {
if err = rows.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username, &user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified, &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, &notifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps, &user.RemoteId, &user.LastLogin, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate); err != nil {
return nil, errors.Wrap(err, "failed to scan values from rows into User entity")
}
if err = json.Unmarshal(props, &user.Props); err != nil {
@ -885,10 +931,10 @@ func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID st
func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
query := us.usersQuery.
Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
LeftJoin("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId).
Where("cm.UserId IS NULL").
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(offset)).Limit(uint64(limit))
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
@ -923,10 +969,10 @@ func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([]
FROM
TeamMembers
WHERE
TeamMembers.UserId = u.Id
TeamMembers.UserId = Users.Id
AND TeamMembers.DeleteAt = 0
) = 0`).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
@ -934,9 +980,9 @@ func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([]
query = applyRoleFilter(query, options.Role, isPostgreSQL)
if options.Inactive {
query = query.Where("u.DeleteAt != 0")
query = query.Where("Users.DeleteAt != 0")
} else if options.Active {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
queryString, args, err := query.ToSql()
@ -965,7 +1011,7 @@ func (us SqlUserStore) GetProfilesByUsernames(usernames []string, viewRestrictio
Where(map[string]any{
"Username": usernames,
}).
OrderBy("u.Username ASC")
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -988,10 +1034,10 @@ type UserWithLastActivityAt struct {
func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
query := us.usersQuery.
Column("s.LastActivityAt").
Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId).
Join("Status s ON (s.UserId = u.Id)").
Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.TeamId = ?)", teamId).
Join("Status s ON (s.UserId = Users.Id)").
OrderBy("s.LastActivityAt DESC").
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(offset)).Limit(uint64(limit))
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
@ -1020,9 +1066,9 @@ func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limi
func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
query := us.usersQuery.
Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId).
OrderBy("u.CreateAt DESC").
OrderBy("u.Username ASC").
Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.TeamId = ?)", teamId).
OrderBy("Users.CreateAt DESC").
OrderBy("Users.Username ASC").
Offset(uint64(offset)).Limit(uint64(limit))
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
@ -1052,13 +1098,13 @@ func (us SqlUserStore) GetProfileByIds(ctx context.Context, userIds []string, op
users := []*model.User{}
query := us.usersQuery.
Where(map[string]any{
"u.Id": userIds,
"Users.Id": userIds,
}).
OrderBy("u.Username ASC")
OrderBy("Users.Username ASC")
if options.Since > 0 {
query = query.Where(sq.Gt(map[string]any{
"u.UpdateAt": options.Since,
"Users.UpdateAt": options.Since,
}))
}
@ -1099,14 +1145,14 @@ func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channel
)`, userId)
query := us.getQueryBuilder().
Select("u.*, cm.ChannelId").
From("Users u").
Join("ChannelMembers cm ON u.Id = cm.UserId").
Select("Users.*, cm.ChannelId").
From("Users").
Join("ChannelMembers cm ON Users.Id = cm.UserId").
Join("Channels c ON cm.ChannelId = c.Id").
Where(sq.Eq{"c.Type": model.ChannelTypeGroup, "cm.ChannelId": channelIds}).
Where(isMemberQuery).
Where(sq.NotEq{"u.Id": userId}).
OrderBy("u.Username ASC")
Where(sq.NotEq{"Users.Id": userId}).
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -1133,7 +1179,7 @@ func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channel
func (us SqlUserStore) GetSystemAdminProfiles() (map[string]*model.User, error) {
query := us.usersQuery.
Where("Roles LIKE ?", "%system_admin%").
OrderBy("u.Username ASC")
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -1201,8 +1247,8 @@ func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.U
}
query := us.usersQuery.
Where("u.AuthData = ?", authData).
Where("u.AuthService = ?", authService)
Where("Users.AuthData = ?", authData).
Where("Users.AuthService = ?", authService)
queryString, args, err := query.ToSql()
if err != nil {
@ -1220,8 +1266,8 @@ func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.U
func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User, error) {
query := us.usersQuery.
Where("u.AuthService = ?", authService).
OrderBy("u.Username ASC")
Where("Users.AuthService = ?", authService).
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -1238,8 +1284,8 @@ func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User
func (us SqlUserStore) GetAllNotInAuthService(authServices []string) ([]*model.User, error) {
query := us.usersQuery.
Where(sq.NotEq{"u.AuthService": authServices}).
OrderBy("u.Username ASC")
Where(sq.NotEq{"Users.AuthService": authServices}).
OrderBy("Users.Username ASC")
queryString, args, err := query.ToSql()
if err != nil {
@ -1255,7 +1301,7 @@ func (us SqlUserStore) GetAllNotInAuthService(authServices []string) ([]*model.U
}
func (us SqlUserStore) GetByUsername(username string) (*model.User, error) {
query := us.usersQuery.Where("u.Username = lower(?)", username)
query := us.usersQuery.Where("Users.Username = lower(?)", username)
queryString, args, err := query.ToSql()
if err != nil {
@ -1324,26 +1370,26 @@ func (us SqlUserStore) PermanentDelete(rctx request.CTX, userId string) error {
}
func (us SqlUserStore) Count(options model.UserCountOptions) (int64, error) {
query := us.getQueryBuilder().Select("COUNT(*)").From("Users AS u")
query := us.getQueryBuilder().Select("COUNT(*)").From("Users")
if !options.IncludeDeleted {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
if !options.IncludeRemoteUsers {
query = query.Where(sq.Or{sq.Eq{"u.RemoteId": ""}, sq.Eq{"u.RemoteId": nil}})
query = query.Where(sq.Or{sq.Eq{"Users.RemoteId": ""}, sq.Eq{"Users.RemoteId": nil}})
}
isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres
if options.IncludeBotAccounts {
if options.ExcludeRegularUsers {
query = query.Join("Bots ON u.Id = Bots.UserId")
query = query.Join("Bots ON Users.Id = Bots.UserId")
}
} else {
if isPostgreSQL {
query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL")
query = query.LeftJoin("Bots ON Users.Id = Bots.UserId").Where("Bots.UserId IS NULL")
} else {
query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)"))
query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)"))
}
if options.ExcludeRegularUsers {
@ -1353,9 +1399,9 @@ func (us SqlUserStore) Count(options model.UserCountOptions) (int64, error) {
}
if options.TeamId != "" {
query = query.LeftJoin("TeamMembers AS tm ON u.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId)
query = query.LeftJoin("TeamMembers AS tm ON Users.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId)
} else if options.ChannelId != "" {
query = query.LeftJoin("ChannelMembers AS cm ON u.Id = cm.UserId").Where("cm.ChannelId = ?", options.ChannelId)
query = query.LeftJoin("ChannelMembers AS cm ON Users.Id = cm.UserId").Where("cm.ChannelId = ?", options.ChannelId)
}
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, false)
query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL)
@ -1451,7 +1497,7 @@ func (us SqlUserStore) AnalyticsActiveCountForPeriod(startTime int64, endTime in
}
func (us SqlUserStore) GetUnreadCount(userId string, isCRTEnabled bool) (int64, error) {
var mentionCountColumn = "cm.MentionCount"
mentionCountColumn := "cm.MentionCount"
if isCRTEnabled {
mentionCountColumn = "cm.MentionCountRoot"
}
@ -1498,7 +1544,7 @@ func (us SqlUserStore) Search(rctx request.CTX, teamId string, term string, opti
Limit(uint64(options.Limit))
if teamId != "" {
query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
query = query.Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
}
return us.performSearch(query, term, options)
}
@ -1511,10 +1557,10 @@ func (us SqlUserStore) SearchWithoutTeam(term string, options *model.UserSearchO
FROM
TeamMembers
WHERE
TeamMembers.UserId = u.Id
TeamMembers.UserId = Users.Id
AND TeamMembers.DeleteAt = 0
) = 0`).
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Limit(uint64(options.Limit))
return us.performSearch(query, term, options)
@ -1522,9 +1568,9 @@ func (us SqlUserStore) SearchWithoutTeam(term string, options *model.UserSearchO
func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, error) {
query := us.usersQuery.
LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", notInTeamId).
LeftJoin("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", notInTeamId).
Where("tm.UserId IS NULL").
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Limit(uint64(options.Limit))
if options.GroupConstrained {
@ -1536,13 +1582,13 @@ func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options
func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, error) {
query := us.usersQuery.
LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
LeftJoin("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId).
Where("cm.UserId IS NULL").
OrderBy("Username ASC").
Limit(uint64(options.Limit))
if teamId != "" {
query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
query = query.Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
}
if options.GroupConstrained {
@ -1554,7 +1600,7 @@ func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term
func (us SqlUserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, error) {
query := us.usersQuery.
Join("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
Join("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId).
OrderBy("Username ASC").
Limit(uint64(options.Limit))
@ -1563,7 +1609,7 @@ func (us SqlUserStore) SearchInChannel(channelId string, term string, options *m
func (us SqlUserStore) SearchInGroup(groupID string, term string, options *model.UserSearchOptions) ([]*model.User, error) {
query := us.usersQuery.
Join("GroupMembers gm ON ( gm.UserId = u.Id AND gm.GroupId = ? AND gm.DeleteAt = 0 )", groupID).
Join("GroupMembers gm ON ( gm.UserId = Users.Id AND gm.GroupId = ? AND gm.DeleteAt = 0 )", groupID).
OrderBy("Username ASC").
Limit(uint64(options.Limit))
@ -1572,7 +1618,7 @@ func (us SqlUserStore) SearchInGroup(groupID string, term string, options *model
func (us SqlUserStore) SearchNotInGroup(groupID string, term string, options *model.UserSearchOptions) ([]*model.User, error) {
query := us.usersQuery.
LeftJoin("GroupMembers gm ON ( gm.UserId = u.Id AND gm.GroupId = ? )", groupID).
LeftJoin("GroupMembers gm ON ( gm.UserId = Users.Id AND gm.GroupId = ? )", groupID).
Where("(gm.UserId IS NULL OR gm.deleteat != 0)").
OrderBy("Username ASC").
Limit(uint64(options.Limit))
@ -1624,7 +1670,7 @@ func (us SqlUserStore) performSearch(query sq.SelectBuilder, term string, option
query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL)
if !options.AllowInactive {
query = query.Where("u.DeleteAt = 0")
query = query.Where("Users.DeleteAt = 0")
}
if strings.TrimSpace(term) != "" {
@ -1671,7 +1717,6 @@ func (us SqlUserStore) AnalyticsGetInactiveUsersCount() (int64, error) {
return int64(0), errors.Wrap(err, "failed to create a SQL query to count inactive users")
}
err = us.GetReplica().Get(&count, queryStr, args...)
if err != nil {
return int64(0), errors.Wrap(err, "failed to count inactive Users")
}
@ -1708,9 +1753,9 @@ func (us SqlUserStore) AnalyticsGetSystemAdminCount() (int64, error) {
func (us SqlUserStore) GetProfilesNotInTeam(teamId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
users := []*model.User{}
query := us.usersQuery.
LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
LeftJoin("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
Where("tm.UserId IS NULL").
OrderBy("u.Username ASC").
OrderBy("Users.Username ASC").
Offset(uint64(offset)).Limit(uint64(limit))
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
@ -1739,9 +1784,9 @@ func (us SqlUserStore) GetEtagForProfilesNotInTeam(teamId string) string {
SELECT
CONCAT(MAX(UpdateAt), '.', COUNT(Id)) as etag
FROM
Users as u
Users
LEFT JOIN TeamMembers tm
ON tm.UserId = u.Id
ON tm.UserId = Users.Id
AND tm.TeamId = ?
AND tm.DeleteAt = 0
WHERE
@ -1822,13 +1867,13 @@ func (us SqlUserStore) GetUsersBatchForIndexing(startTime int64, startFileID str
users := []*model.User{}
usersQuery, args, err := us.usersQuery.
Where(sq.Or{
sq.Gt{"u.CreateAt": startTime},
sq.Gt{"Users.CreateAt": startTime},
sq.And{
sq.Eq{"u.CreateAt": startTime},
sq.Gt{"u.Id": startFileID},
sq.Eq{"Users.CreateAt": startTime},
sq.Gt{"Users.Id": startFileID},
},
}).
OrderBy("u.CreateAt ASC, u.Id ASC").
OrderBy("Users.CreateAt ASC, Users.Id ASC").
Limit(uint64(limit)).
ToSql()
if err != nil {
@ -1996,10 +2041,10 @@ func applyViewRestrictionsFilter(query sq.SelectBuilder, restrictions *model.Vie
}
resultQuery := query
if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = u.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = Users.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
}
if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = u.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = Users.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
}
if distinct {
@ -2225,22 +2270,21 @@ func (us SqlUserStore) IsEmpty(excludeBots bool) (bool, error) {
func (us SqlUserStore) GetUsersWithInvalidEmails(page int, perPage int, restrictedDomains string) ([]*model.User, error) {
domainArray := strings.Split(restrictedDomains, ",")
query := us.usersQuery.
LeftJoin("Bots ON u.Id = Bots.UserId").
LeftJoin("Bots ON Users.Id = Bots.UserId").
Where("Bots.UserId IS NULL").
Where("u.Roles != 'system_guest'").
Where("u.DeleteAt = 0").
Where("(u.AuthService = '' OR u.AuthService IS NULL)")
Where("Users.Roles != 'system_guest'").
Where("Users.DeleteAt = 0").
Where("(Users.AuthService = '' OR Users.AuthService IS NULL)")
for _, d := range domainArray {
if d != "" {
query = query.Where("u.Email NOT LIKE LOWER(?)", wildcardSearchTerm(d))
query = query.Where("Users.Email NOT LIKE LOWER(?)", wildcardSearchTerm(d))
}
}
query = query.Offset(uint64(page * perPage)).Limit(uint64(perPage))
queryString, args, err := query.ToSql()
if err != nil {
return nil, errors.Wrap(err, "users_get_many_tosql")
}
@ -2272,16 +2316,16 @@ func (us SqlUserStore) RefreshPostStatsForUsers() error {
func applyUserReportFilter(query sq.SelectBuilder, filter *model.UserReportOptions, isPostgres bool) sq.SelectBuilder {
query = applyRoleFilter(query, filter.Role, isPostgres)
if filter.HasNoTeam {
query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM TeamMembers WHERE DeleteAt = 0)"))
query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM TeamMembers WHERE DeleteAt = 0)"))
} else if filter.Team != "" {
query = query.Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.DeleteAt = 0)").
query = query.Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.DeleteAt = 0)").
Where(sq.Eq{"tm.TeamId": filter.Team})
}
if filter.HideActive {
query = query.Where(sq.Gt{"u.DeleteAt": 0})
query = query.Where(sq.Gt{"Users.DeleteAt": 0})
}
if filter.HideInactive {
query = query.Where(sq.Eq{"u.DeleteAt": 0})
query = query.Where(sq.Eq{"Users.DeleteAt": 0})
}
if strings.TrimSpace(filter.SearchTerm) != "" {
@ -2294,13 +2338,13 @@ func applyUserReportFilter(query sq.SelectBuilder, filter *model.UserReportOptio
func (us SqlUserStore) GetUserCountForReport(filter *model.UserReportOptions) (int64, error) {
isPostgres := us.DriverName() == model.DatabaseDriverPostgres
query := us.getQueryBuilder().
Select("COUNT(u.Id)").
From("Users u")
Select("COUNT(Users.Id)").
From("Users")
if isPostgres {
query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL")
query = query.LeftJoin("Bots ON Users.Id = Bots.UserId").Where("Bots.UserId IS NULL")
} else {
query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)"))
query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)"))
}
query = applyUserReportFilter(query, filter, isPostgres)
@ -2318,7 +2362,7 @@ func (us SqlUserStore) GetUserCountForReport(filter *model.UserReportOptions) (i
func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.UserReportQuery, error) {
isPostgres := us.DriverName() == model.DatabaseDriverPostgres
selectColumns := []string{"u.*", "MAX(s.LastActivityAt) AS LastStatusAt"}
selectColumns := []string{"Users.*", "MAX(s.LastActivityAt) AS LastStatusAt"}
if isPostgres {
selectColumns = append(selectColumns,
"MAX(ps.LastPostDate) AS LastPostDate",
@ -2334,10 +2378,10 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
query := us.getQueryBuilder().
Select(selectColumns...).
From("Users u").
LeftJoin("Status s ON s.UserId = u.Id").
Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")).
GroupBy("u.Id")
From("Users").
LeftJoin("Status s ON s.UserId = Users.Id").
Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)")).
GroupBy("Users.Id")
// no need to apply any filtering and pagination if there are no
// previous element ID and value provided.
@ -2349,7 +2393,7 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
sq.Lt{filter.SortColumn: filter.FromColumnValue},
sq.And{
sq.Eq{filter.SortColumn: filter.FromColumnValue},
sq.Lt{"u.Id": filter.FromId},
sq.Lt{"Users.Id": filter.FromId},
},
})
} else {
@ -2359,13 +2403,13 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
sq.Gt{filter.SortColumn: filter.FromColumnValue},
sq.And{
sq.Eq{filter.SortColumn: filter.FromColumnValue},
sq.Gt{"u.Id": filter.FromId},
sq.Gt{"Users.Id": filter.FromId},
},
})
}
}
query = query.OrderBy(filter.SortColumn+" "+sortDirection, "u.Id")
query = query.OrderBy(filter.SortColumn+" "+sortDirection, "Users.Id")
if filter.PageSize > 0 {
query = query.Limit(uint64(filter.PageSize))
@ -2385,7 +2429,7 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
if err != nil {
return nil, err
}
query = query.LeftJoin("PostStats ps ON ps.UserId = u.Id AND "+sql, args...)
query = query.LeftJoin("PostStats ps ON ps.UserId = Users.Id AND "+sql, args...)
}
query = applyUserReportFilter(query, filter, isPostgres)