[MM-63196] Channel sql store migrate select * to specific columns (#30255)

* Adde MySQL and Postgres migrations

* Replaced select * with column names

* removed all * from channel SQL store

* cleanup

* Fixed a duplicate column

* cleanup

* used channelname slice in a missed place

* WIP

* converted to query builder

* cleanupo

* Review fixes
Этот коммит содержится в:
Harshil Sharma
2025-02-24 09:13:12 +05:30
коммит произвёл GitHub
родитель fa9af97727
Коммит 920b3301e5

Просмотреть файл

@@ -105,6 +105,39 @@ func channelMemberSliceColumns() []string {
return []string{"ChannelId", "UserId", "Roles", "LastViewedAt", "MsgCount", "MsgCountRoot", "MentionCount", "MentionCountRoot", "UrgentMentionCount", "NotifyProps", "LastUpdateAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
}
// channelSliceColumns returns fields of the channel as a string slice.
// Optionally, you can add a prefix (accepts only 1 value) to the fields.
func channelSliceColumns(prefix ...string) []string {
var p string
if len(prefix) == 1 {
p = prefix[0] + "."
} else if len(prefix) > 1 {
panic("cannot accept multiple prefixes")
}
return []string{
p + "Id",
p + "CreateAt",
p + "UpdateAt",
p + "DeleteAt",
p + "TeamId",
p + "Type",
p + "DisplayName",
p + "Name",
p + "Header",
p + "Purpose",
p + "LastPostAt",
p + "TotalMsgCount",
p + "ExtraUpdateAt",
p + "CreatorId",
p + "SchemeId",
p + "GroupConstrained",
p + "Shared",
p + "TotalMsgCountRoot",
p + "LastRootPostAt",
}
}
func channelMemberToSlice(member *model.ChannelMember) []any {
resultSlice := []any{}
resultSlice = append(resultSlice, member.ChannelId)
@@ -124,6 +157,30 @@ func channelMemberToSlice(member *model.ChannelMember) []any {
return resultSlice
}
func channelToSlice(channel *model.Channel) []interface{} {
return []interface{}{
channel.Id,
channel.CreateAt,
channel.UpdateAt,
channel.DeleteAt,
channel.TeamId,
channel.Type,
channel.DisplayName,
channel.Name,
channel.Header,
channel.Purpose,
channel.LastPostAt,
channel.TotalMsgCount,
channel.ExtraUpdateAt,
channel.CreatorId,
channel.SchemeId,
channel.GroupConstrained,
channel.Shared,
channel.TotalMsgCountRoot,
channel.LastRootPostAt,
}
}
type channelMemberWithSchemeRolesList []channelMemberWithSchemeRoles
func getChannelRoles(schemeGuest, schemeUser, schemeAdmin bool, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, defaultChannelGuestRole, defaultChannelUserRole, defaultChannelAdminRole string,
@@ -446,10 +503,7 @@ func newSqlChannelStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface
metrics: metrics,
}
s.tableSelectQuery = s.getQueryBuilder().Select("Id", "CreateAt", "UpdateAt", "DeleteAt", "TeamId", "Type", "DisplayName",
"Name", "Header", "Purpose", "LastPostAt", "TotalMsgCount", "ExtraUpdateAt", "CreatorId", "SchemeId", "GroupConstrained",
"Shared", "TotalMsgCountRoot", "LastRootPostAt",
).From("Channels")
s.tableSelectQuery = s.getQueryBuilder().Select(channelSliceColumns()...).From("Channels")
s.initializeQueries()
@@ -681,21 +735,27 @@ func (s SqlChannelStore) saveChannelT(transaction *sqlxTxWrapper, channel *model
}
}
var insert string
var insert sq.InsertBuilder
if s.DriverName() == model.DatabaseDriverMysql {
insert = `INSERT IGNORE INTO Channels
(Id, CreateAt, UpdateAt, DeleteAt, TeamId, Type, DisplayName, Name, Header, Purpose, LastPostAt, TotalMsgCount, ExtraUpdateAt, CreatorId, SchemeId, GroupConstrained, Shared, TotalMsgCountRoot, LastRootPostAt)
VALUES
(:Id, :CreateAt, :UpdateAt, :DeleteAt, :TeamId, :Type, :DisplayName, :Name, :Header, :Purpose, :LastPostAt, :TotalMsgCount, :ExtraUpdateAt, :CreatorId, :SchemeId, :GroupConstrained, :Shared, :TotalMsgCountRoot, :LastRootPostAt)`
insert = s.getQueryBuilder().
Insert("Channels").
Options("IGNORE").
Columns(channelSliceColumns()...).
Values(channelToSlice(channel)...)
} else {
insert = `INSERT INTO Channels
(Id, CreateAt, UpdateAt, DeleteAt, TeamId, Type, DisplayName, Name, Header, Purpose, LastPostAt, TotalMsgCount, ExtraUpdateAt, CreatorId, SchemeId, GroupConstrained, Shared, TotalMsgCountRoot, LastRootPostAt)
VALUES
(:Id, :CreateAt, :UpdateAt, :DeleteAt, :TeamId, :Type, :DisplayName, :Name, :Header, :Purpose, :LastPostAt, :TotalMsgCount, :ExtraUpdateAt, :CreatorId, :SchemeId, :GroupConstrained, :Shared, :TotalMsgCountRoot, :LastRootPostAt)
ON CONFLICT (TeamId, Name) DO NOTHING`
insert = s.getQueryBuilder().
Insert("Channels").
Columns(channelSliceColumns()...).
Values(channelToSlice(channel)...).
SuffixExpr(sq.Expr("ON CONFLICT (TeamId, Name) DO NOTHING"))
}
insertResult, err := transaction.NamedExec(insert, channel)
query, params, err := insert.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "save_channel: id=%s", channel.Id)
}
insertResult, err := transaction.Exec(query, params...)
if err != nil {
return nil, errors.Wrapf(err, "save_channel: id=%s", channel.Id)
@@ -858,7 +918,7 @@ func (s SqlChannelStore) Get(id string, allowFromCache bool) (*model.Channel, er
//nolint:unparam
func (s SqlChannelStore) GetMany(ids []string, allowFromCache bool) (model.ChannelList, error) {
query := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(sq.Eq{"Id": ids})
sql, args, err := query.ToSql()
@@ -1020,7 +1080,7 @@ func (s SqlChannelStore) PermanentDeleteMembersByChannel(rctx request.CTX, chann
func (s SqlChannelStore) GetChannels(teamId string, userId string, opts *model.ChannelSearchOpts) (model.ChannelList, error) {
query := s.getQueryBuilder().
Select("ch.*").
Select(channelSliceColumns("ch")...).
From("Channels ch, ChannelMembers cm").
Where(
sq.And{
@@ -1075,7 +1135,7 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string, opts *model.C
func (s SqlChannelStore) GetChannelsByUser(userId string, includeDeleted bool, lastDeleteAt, pageSize int, fromChannelID string) (model.ChannelList, error) {
query := s.getQueryBuilder().
Select("Channels.*").
Select(channelSliceColumns("Channels")...).
From("Channels, ChannelMembers").
Where(
sq.And{
@@ -1177,18 +1237,25 @@ func (s SqlChannelStore) GetAllChannelsCount(opts store.ChannelSearchOpts) (int6
}
func (s SqlChannelStore) getAllChannelsQuery(opts store.ChannelSearchOpts, forCount bool) sq.SelectBuilder {
var selectStr string
var selectQuery sq.SelectBuilder
if forCount {
selectStr = "count(c.Id)"
selectQuery = s.getQueryBuilder().
Select("count(c.Id)")
} else {
selectStr = "c.*, Teams.DisplayName AS TeamDisplayName, Teams.Name AS TeamName, Teams.UpdateAt AS TeamUpdateAt"
selectQuery = s.getQueryBuilder().
Select(channelSliceColumns("c")...).
Columns(
"Teams.DisplayName AS TeamDisplayName",
"Teams.Name AS TeamName",
"Teams.UpdateAt AS TeamUpdateAt",
)
if opts.IncludePolicyID {
selectStr += ", RetentionPoliciesChannels.PolicyId AS PolicyID"
selectQuery = selectQuery.Columns("RetentionPoliciesChannels.PolicyId AS PolicyID")
}
}
query := s.getQueryBuilder().
Select(selectStr).
query := selectQuery.
From("Channels AS c").
Where(sq.Eq{"c.Type": []model.ChannelType{model.ChannelTypePrivate, model.ChannelTypeOpen}})
@@ -1228,35 +1295,31 @@ func (s SqlChannelStore) getAllChannelsQuery(opts store.ChannelSearchOpts, forCo
}
func (s SqlChannelStore) GetMoreChannels(teamId string, userId string, offset int, limit int) (model.ChannelList, error) {
channels := model.ChannelList{}
err := s.GetReplica().Select(&channels, `
SELECT
Channels.*
FROM
Channels
JOIN
PublicChannels c ON (c.Id = Channels.Id)
WHERE
c.TeamId = ?
AND c.DeleteAt = 0
AND c.Id NOT IN (
SELECT
c.Id
FROM
PublicChannels c
JOIN
ChannelMembers cm ON (cm.ChannelId = c.Id)
WHERE
c.TeamId = ?
AND cm.UserId = ?
AND c.DeleteAt = 0
)
ORDER BY
c.DisplayName
LIMIT ?
OFFSET ?
`, teamId, teamId, userId, limit, offset)
subQuery := s.getSubQueryBuilder().
Select("c.Id").
From("PublicChannels c").
Join("ChannelMembers cm ON (cm.ChannelId = c.Id)").
Where(sq.Eq{
"c.TeamId": teamId,
"cm.UserId": userId,
"c.DeleteAt": 0,
})
query := s.getQueryBuilder().
Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels c ON (c.Id = Channels.Id)").
Where(sq.Eq{
"c.TeamId": teamId,
"c.DeleteAt": 0,
}).
Where(sq.Expr("c.Id NOT IN (?)", subQuery)).
OrderBy("c.DisplayName").
Limit(uint64(limit)).
Offset(uint64(offset))
channels := model.ChannelList{}
err := s.GetReplica().SelectBuilder(&channels, query)
if err != nil {
return nil, errors.Wrapf(err, "failed getting channels with teamId=%s and userId=%s", teamId, userId)
}
@@ -1268,7 +1331,7 @@ func (s SqlChannelStore) GetPrivateChannelsForTeam(teamId string, offset int, li
channels := model.ChannelList{}
builder := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(sq.Eq{"Type": model.ChannelTypePrivate, "TeamId": teamId, "DeleteAt": 0}).
OrderBy("DisplayName").
@@ -1288,22 +1351,26 @@ func (s SqlChannelStore) GetPrivateChannelsForTeam(teamId string, offset int, li
}
func (s SqlChannelStore) GetPublicChannelsForTeam(teamId string, offset int, limit int) (model.ChannelList, error) {
channels := model.ChannelList{}
err := s.GetReplica().Select(&channels, `
SELECT
Channels.*
FROM
Channels
JOIN
PublicChannels pc ON (pc.Id = Channels.Id)
WHERE
pc.TeamId = ?
AND pc.DeleteAt = 0
ORDER BY pc.DisplayName
LIMIT ?
OFFSET ?
`, teamId, limit, offset)
query := s.getQueryBuilder().
Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels pc ON (pc.Id = Channels.Id)").
Where(sq.Eq{
"pc.TeamId": teamId,
"pc.DeleteAt": 0,
}).
OrderBy("pc.DisplayName").
Limit(uint64(limit)).
Offset(uint64(offset))
channels := model.ChannelList{}
queryString, args, err := query.ToSql()
if err != nil {
return nil, errors.Wrap(err, "failed to convert query to string")
}
err = s.GetReplica().Select(&channels, queryString, args...)
if err != nil {
return nil, errors.Wrapf(err, "failed to find channel with teamId=%s", teamId)
}
@@ -1329,7 +1396,7 @@ func (s SqlChannelStore) GetPublicChannelsByIdsForTeam(teamId string, channelIds
var data model.ChannelList
builder := s.getQueryBuilder().
Select("Channels.*").
Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels pc ON (pc.Id = Channels.Id)").
Where(sq.And{
@@ -1424,7 +1491,7 @@ func (s SqlChannelStore) getByNames(teamId string, names []string, allowFromCach
}
builder := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(cond)
@@ -1459,7 +1526,7 @@ func (s SqlChannelStore) GetByName(teamId string, name string, allowFromCache bo
func (s SqlChannelStore) getByName(teamId string, name string, includeDeleted bool, allowFromCache bool) (*model.Channel, error) {
query := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(sq.Eq{"Name": name}).
Where(sq.Or{
@@ -1510,7 +1577,7 @@ func (s SqlChannelStore) GetDeleted(teamId string, offset int, limit int, userId
channels := model.ChannelList{}
builder := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(sq.Or{
sq.Eq{"TeamId": teamId},
@@ -2841,7 +2908,7 @@ func (s SqlChannelStore) GetAll(teamId string) ([]*model.Channel, error) {
func (s SqlChannelStore) GetChannelsByIds(channelIds []string, includeDeleted bool) ([]*model.Channel, error) {
query := s.getQueryBuilder().
Select("*").
Select(channelSliceColumns()...).
From("Channels").
Where(sq.Eq{"Id": channelIds}).
OrderBy("Name")
@@ -2865,10 +2932,12 @@ func (s SqlChannelStore) GetChannelsByIds(channelIds []string, includeDeleted bo
func (s SqlChannelStore) GetChannelsWithTeamDataByIds(channelIDs []string, includeDeleted bool) ([]*model.ChannelWithTeamData, error) {
query := s.getQueryBuilder().
Select("c.*",
Select(channelSliceColumns("c")...).
Columns(
"COALESCE(t.DisplayName, '') As TeamDisplayName",
"COALESCE(t.Name, '') AS TeamName",
"COALESCE(t.UpdateAt, 0) AS TeamUpdateAt").
"COALESCE(t.UpdateAt, 0) AS TeamUpdateAt",
).
From("Channels c").
LeftJoin("Teams t ON c.TeamId = t.Id").
Where(sq.Eq{"c.Id": channelIDs}).
@@ -2892,19 +2961,26 @@ func (s SqlChannelStore) GetChannelsWithTeamDataByIds(channelIDs []string, inclu
}
func (s SqlChannelStore) GetForPost(postId string) (*model.Channel, error) {
query := s.getQueryBuilder().
Select(channelSliceColumns("Channels")...).
From("Channels").
Join("Posts ON Channels.Id = Posts.ChannelId").
Where(sq.Eq{
"Posts.Id": postId,
})
queryString, argss, err := query.ToSql()
if err != nil {
return nil, errors.Wrap(err, "GetForPost: failed to convert query to string")
}
channel := model.Channel{}
if err := s.GetReplica().Get(
&channel,
`SELECT
Channels.*
FROM
Channels,
Posts
WHERE
Channels.Id = Posts.ChannelId
AND Posts.Id = ?`, postId); err != nil {
err = s.GetReplica().Get(&channel, queryString, argss...)
if err != nil {
return nil, errors.Wrapf(err, "failed to get Channel with postId=%s", postId)
}
return &channel, nil
}
@@ -3047,10 +3123,13 @@ func (s SqlChannelStore) GetTeamMembersForChannel(channelID string) ([]string, e
}
func (s SqlChannelStore) Autocomplete(rctx request.CTX, userID, term string, includeDeleted, isGuest bool) (model.ChannelListWithTeamData, error) {
query := s.getQueryBuilder().Select("c.*",
"t.DisplayName AS TeamDisplayName",
"t.Name AS TeamName",
"t.UpdateAt AS TeamUpdateAt").
query := s.getQueryBuilder().
Select(channelSliceColumns("c")...).
Columns(
"t.DisplayName AS TeamDisplayName",
"t.Name AS TeamName",
"t.UpdateAt AS TeamUpdateAt",
).
From("Channels c, Teams t, TeamMembers tm").
Where(sq.And{
sq.Expr("c.TeamId = t.id"),
@@ -3102,7 +3181,7 @@ func (s SqlChannelStore) Autocomplete(rctx request.CTX, userID, term string, inc
}
func (s SqlChannelStore) AutocompleteInTeam(rctx request.CTX, teamID, userID, term string, includeDeleted, isGuest bool) (model.ChannelList, error) {
query := s.getQueryBuilder().Select("*").
query := s.getQueryBuilder().Select(channelSliceColumns()...).
From("Channels c").
Where(sq.Eq{"c.TeamId": teamID}).
OrderBy("c.DisplayName").
@@ -3138,7 +3217,7 @@ func (s SqlChannelStore) AutocompleteInTeam(rctx request.CTX, teamID, userID, te
func (s SqlChannelStore) AutocompleteInTeamForSearch(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
// shared query
query := s.getSubQueryBuilder().Select("C.*").
query := s.getSubQueryBuilder().Select(channelSliceColumns("C")...).
From("Channels AS C").
Join("ChannelMembers AS CM ON CM.ChannelId = C.Id").
Limit(50).
@@ -3228,7 +3307,9 @@ func (s SqlChannelStore) AutocompleteInTeamForSearch(teamID string, userID strin
func (s SqlChannelStore) autocompleteInTeamForSearchDirectMessages(userID string, term string) ([]*model.Channel, error) {
// create the main query
query := s.getQueryBuilder().Select("C.*", "OtherUsers.Username as DisplayName").
query := s.getQueryBuilder().
Select(channelSliceColumns("C")...).
Columns("OtherUsers.Username AS DisplayName").
From("Channels AS C").
Join("ChannelMembers AS CM ON CM.ChannelId = C.Id").
Where(sq.Eq{
@@ -3272,7 +3353,7 @@ func (s SqlChannelStore) autocompleteInTeamForSearchDirectMessages(userID string
}
func (s SqlChannelStore) SearchInTeam(teamId string, term string, includeDeleted bool) (model.ChannelList, error) {
query := s.getQueryBuilder().Select("Channels.*").
query := s.getQueryBuilder().Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels c ON (c.Id = Channels.Id)").
Where(sq.Eq{"c.TeamId": teamId}).
@@ -3294,7 +3375,7 @@ func (s SqlChannelStore) SearchInTeam(teamId string, term string, includeDeleted
}
func (s SqlChannelStore) SearchArchivedInTeam(teamId string, term string, userId string) (model.ChannelList, error) {
queryBase := s.getQueryBuilder().Select("Channels.*").
queryBase := s.getQueryBuilder().Select(channelSliceColumns("Channels")...).
From("Channels").
Join("Channels c ON (c.Id = Channels.Id)").
Where(sq.And{
@@ -3338,7 +3419,7 @@ func (s SqlChannelStore) SearchArchivedInTeam(teamId string, term string, userId
}
func (s SqlChannelStore) SearchForUserInTeam(userId string, teamId string, term string, includeDeleted bool) (model.ChannelList, error) {
query := s.getQueryBuilder().Select("Channels.*").
query := s.getQueryBuilder().Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels c ON (c.Id = Channels.Id)").
Join("ChannelMembers cm ON (c.Id = cm.ChannelId)").
@@ -3369,21 +3450,25 @@ func (s SqlChannelStore) channelSearchQuery(opts *store.ChannelSearchOpts) sq.Se
limit = 100
}
var selectStr string
var selectQuery sq.SelectBuilder
if opts.CountOnly {
selectStr = "count(*)"
selectQuery = s.getQueryBuilder().Select("count(*)")
} else {
selectStr = "c.*"
selectQuery = s.getQueryBuilder().
Select(channelSliceColumns("c")...)
if opts.IncludeTeamInfo {
selectStr += ", t.DisplayName AS TeamDisplayName, t.Name AS TeamName, t.UpdateAt as TeamUpdateAt"
selectQuery = selectQuery.Columns(
"t.DisplayName AS TeamDisplayName",
"t.Name AS TeamName",
"t.UpdateAt as TeamUpdateAt",
)
}
if opts.IncludePolicyID {
selectStr += ", RetentionPoliciesChannels.PolicyId AS PolicyID"
selectQuery = selectQuery.Columns("RetentionPoliciesChannels.PolicyId AS PolicyID")
}
}
query := s.getQueryBuilder().
Select(selectStr).
query := selectQuery.
From("Channels AS c").
Join("Teams AS t ON t.Id = c.TeamId")
@@ -3530,7 +3615,7 @@ func (s SqlChannelStore) SearchMore(userId string, teamId string, term string) (
"c.DeleteAt": 0,
})
query := s.getQueryBuilder().Select("Channels.*").
query := s.getQueryBuilder().Select(channelSliceColumns("Channels")...).
From("Channels").
Join("PublicChannels c ON (c.Id=Channels.Id)").
Where(sq.And{
@@ -3737,7 +3822,7 @@ func (s SqlChannelStore) searchGroupChannelsQuery(userId, term string, isPostgre
Having(having).
Limit(model.ChannelSearchDefaultLimit)
return s.getQueryBuilder().Select("*").
return s.getQueryBuilder().Select(channelSliceColumns()...).
From("Channels").
Where(sq.Expr("Id IN (?)", subq))
}
@@ -3749,7 +3834,7 @@ func (s SqlChannelStore) searchGroupChannelsQuery(userId, term string, isPostgre
having = append(having, sq.Expr(baseLikeTerm, "%"+term+"%"))
}
cc := s.getSubQueryBuilder().Select("c.*").
cc := s.getSubQueryBuilder().Select(channelSliceColumns("c")...).
From("Channels c").
Join("ChannelMembers cm ON c.Id=cm.ChannelId").
Join("Users u on u.Id = cm.UserId").
@@ -4082,24 +4167,29 @@ func (s SqlChannelStore) ClearAllCustomRoleAssignments() (err error) {
}
func (s SqlChannelStore) GetAllChannelsForExportAfter(limit int, afterId string) ([]*model.ChannelForExport, error) {
query := s.getQueryBuilder().
Select(channelSliceColumns("Channels")...).
Columns(
"Teams.Name as TeamName",
"Schemes.Name as SchemeName",
).
From("Channels").
InnerJoin("Teams ON Channels.TeamId = Teams.Id").
LeftJoin("Schemes ON Channels.SchemeId = Schemes.Id").
Where(sq.And{
sq.Gt{"Channels.Id": afterId},
sq.Eq{"Channels.Type": []model.ChannelType{model.ChannelTypeOpen, model.ChannelTypePrivate}},
}).
OrderBy("Id").
Limit(uint64(limit))
channels := []*model.ChannelForExport{}
if err := s.GetReplica().Select(&channels, `
SELECT
Channels.*,
Teams.Name as TeamName,
Schemes.Name as SchemeName
FROM Channels
INNER JOIN
Teams ON Channels.TeamId = Teams.Id
LEFT JOIN
Schemes ON Channels.SchemeId = Schemes.Id
WHERE
Channels.Id > ?
AND Channels.Type IN (?, ?)
ORDER BY
Id
LIMIT ?`,
afterId, model.ChannelTypeOpen, model.ChannelTypePrivate, limit); err != nil {
queryString, args, err := query.ToSql()
if err != nil {
return nil, errors.Wrap(err, "failed to convert SQL query to string")
}
if err := s.GetReplica().Select(&channels, queryString, args...); err != nil {
return nil, errors.Wrap(err, "failed to find Channels for export")
}
@@ -4146,7 +4236,7 @@ func (s SqlChannelStore) GetChannelMembersForExport(userId string, teamId string
func (s SqlChannelStore) GetAllDirectChannelsForExportAfter(limit int, afterId string, includeArchivedChannels bool) ([]*model.DirectChannelForExport, error) {
directChannelsForExport := []*model.DirectChannelForExport{}
query := s.getQueryBuilder().
Select("Channels.*").
Select(channelSliceColumns("Channels")...).
From("Channels").
Where(sq.And{
sq.Gt{"Channels.Id": afterId},