Channel banner sql migrations (#30274)
* Adde MySQL and Postgres migrations * Replaced select * with column names * removed all * from channel SQL store * cleanup * Fixed a duplicate column * cleanup * Added migrations and store support * WIP * used channelname slice in a missed place * Handled patch * Added app level tests * Added API layer tests * Added API layer tests * WIP * converted to query builder * cleanupo * added not null and default constraints * Fixed test * fixed file name * review fixes * review fixes * updated migration file * fixed text * Review fixes
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6df8726321
Коммит
6e738f489f
@@ -135,28 +135,10 @@ func channelSliceColumns(prefix ...string) []string {
|
||||
p + "Shared",
|
||||
p + "TotalMsgCountRoot",
|
||||
p + "LastRootPostAt",
|
||||
p + "BannerInfo",
|
||||
}
|
||||
}
|
||||
|
||||
func channelMemberToSlice(member *model.ChannelMember) []any {
|
||||
resultSlice := []any{}
|
||||
resultSlice = append(resultSlice, member.ChannelId)
|
||||
resultSlice = append(resultSlice, member.UserId)
|
||||
resultSlice = append(resultSlice, member.ExplicitRoles)
|
||||
resultSlice = append(resultSlice, member.LastViewedAt)
|
||||
resultSlice = append(resultSlice, member.MsgCount)
|
||||
resultSlice = append(resultSlice, member.MsgCountRoot)
|
||||
resultSlice = append(resultSlice, member.MentionCount)
|
||||
resultSlice = append(resultSlice, member.MentionCountRoot)
|
||||
resultSlice = append(resultSlice, member.UrgentMentionCount)
|
||||
resultSlice = append(resultSlice, model.MapToJSON(member.NotifyProps))
|
||||
resultSlice = append(resultSlice, member.LastUpdateAt)
|
||||
resultSlice = append(resultSlice, member.SchemeUser)
|
||||
resultSlice = append(resultSlice, member.SchemeAdmin)
|
||||
resultSlice = append(resultSlice, member.SchemeGuest)
|
||||
return resultSlice
|
||||
}
|
||||
|
||||
func channelToSlice(channel *model.Channel) []interface{} {
|
||||
return []interface{}{
|
||||
channel.Id,
|
||||
@@ -178,9 +160,29 @@ func channelToSlice(channel *model.Channel) []interface{} {
|
||||
channel.Shared,
|
||||
channel.TotalMsgCountRoot,
|
||||
channel.LastRootPostAt,
|
||||
channel.BannerInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func channelMemberToSlice(member *model.ChannelMember) []any {
|
||||
resultSlice := []any{}
|
||||
resultSlice = append(resultSlice, member.ChannelId)
|
||||
resultSlice = append(resultSlice, member.UserId)
|
||||
resultSlice = append(resultSlice, member.ExplicitRoles)
|
||||
resultSlice = append(resultSlice, member.LastViewedAt)
|
||||
resultSlice = append(resultSlice, member.MsgCount)
|
||||
resultSlice = append(resultSlice, member.MsgCountRoot)
|
||||
resultSlice = append(resultSlice, member.MentionCount)
|
||||
resultSlice = append(resultSlice, member.MentionCountRoot)
|
||||
resultSlice = append(resultSlice, member.UrgentMentionCount)
|
||||
resultSlice = append(resultSlice, model.MapToJSON(member.NotifyProps))
|
||||
resultSlice = append(resultSlice, member.LastUpdateAt)
|
||||
resultSlice = append(resultSlice, member.SchemeUser)
|
||||
resultSlice = append(resultSlice, member.SchemeAdmin)
|
||||
resultSlice = append(resultSlice, member.SchemeGuest)
|
||||
return resultSlice
|
||||
}
|
||||
|
||||
type channelMemberWithSchemeRolesList []channelMemberWithSchemeRoles
|
||||
|
||||
func getChannelRoles(schemeGuest, schemeUser, schemeAdmin bool, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, defaultChannelGuestRole, defaultChannelUserRole, defaultChannelAdminRole string,
|
||||
@@ -834,7 +836,8 @@ func (s SqlChannelStore) updateChannelT(transaction *sqlxTxWrapper, channel *mod
|
||||
GroupConstrained=:GroupConstrained,
|
||||
Shared=:Shared,
|
||||
TotalMsgCountRoot=:TotalMsgCountRoot,
|
||||
LastRootPostAt=:LastRootPostAt
|
||||
LastRootPostAt=:LastRootPostAt,
|
||||
BannerInfo=:BannerInfo
|
||||
WHERE Id=:Id`, channel)
|
||||
if err != nil {
|
||||
if IsUniqueConstraintError(err, []string{"Name", "channels_name_teamid_key"}) {
|
||||
|
||||
@@ -206,6 +206,24 @@ func testChannelStoreSave(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
_, nErr = ss.Channel().Save(rctx, &o2, -1)
|
||||
require.Error(t, nErr, "should have failed to save a duplicate of an archived channel")
|
||||
require.True(t, errors.As(nErr, &cErr))
|
||||
|
||||
o1 = model.Channel{}
|
||||
o1.TeamId = teamID
|
||||
o1.DisplayName = "Name"
|
||||
o1.Name = NewTestID()
|
||||
o1.Type = model.ChannelTypeOpen
|
||||
o1.BannerInfo = &model.ChannelBannerInfo{
|
||||
Enabled: model.NewPointer(true),
|
||||
Text: model.NewPointer("banner text"),
|
||||
BackgroundColor: model.NewPointer("#000000"),
|
||||
}
|
||||
|
||||
savedChannel, nErr := ss.Channel().Save(rctx, &o1, -1)
|
||||
require.NoError(t, nErr, "should have saved channel")
|
||||
require.NotNil(t, savedChannel.BannerInfo)
|
||||
require.True(t, *savedChannel.BannerInfo.Enabled)
|
||||
require.Equal(t, "banner text", *savedChannel.BannerInfo.Text)
|
||||
require.Equal(t, "#000000", *savedChannel.BannerInfo.BackgroundColor)
|
||||
}
|
||||
|
||||
func testChannelStoreSaveDirectChannel(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
@@ -369,6 +387,46 @@ func testChannelStoreUpdate(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
var uniqueConstraintErr *store.ErrUniqueConstraint
|
||||
require.ErrorAs(t, err, &uniqueConstraintErr)
|
||||
require.Contains(t, uniqueConstraintErr.Columns, "Name")
|
||||
|
||||
channel := model.Channel{}
|
||||
channel.TeamId = model.NewId()
|
||||
channel.DisplayName = "Name"
|
||||
channel.Name = NewTestID()
|
||||
channel.Type = model.ChannelTypeOpen
|
||||
|
||||
_, nErr = ss.Channel().Save(rctx, &channel, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
channel.BannerInfo = &model.ChannelBannerInfo{
|
||||
Enabled: model.NewPointer(true),
|
||||
Text: model.NewPointer("banner text"),
|
||||
BackgroundColor: model.NewPointer("#000000"),
|
||||
}
|
||||
|
||||
updatedChannel, err := ss.Channel().Update(rctx, &channel)
|
||||
require.NoError(t, err, err)
|
||||
require.NotNil(t, updatedChannel.BannerInfo)
|
||||
require.True(t, *updatedChannel.BannerInfo.Enabled)
|
||||
require.Equal(t, "banner text", *updatedChannel.BannerInfo.Text)
|
||||
require.Equal(t, "#000000", *updatedChannel.BannerInfo.BackgroundColor)
|
||||
|
||||
// can turn off channel banners
|
||||
channel.BannerInfo.Enabled = model.NewPointer(false)
|
||||
|
||||
updatedChannel, err = ss.Channel().Update(rctx, &channel)
|
||||
require.NoError(t, err, err)
|
||||
require.NotNil(t, updatedChannel.BannerInfo)
|
||||
require.False(t, *updatedChannel.BannerInfo.Enabled)
|
||||
|
||||
// can update text and color of channel banners
|
||||
channel.BannerInfo.Text = model.NewPointer("updated text")
|
||||
channel.BannerInfo.BackgroundColor = model.NewPointer("#FFFFFF")
|
||||
|
||||
updatedChannel, err = ss.Channel().Update(rctx, &channel)
|
||||
require.NoError(t, err, err)
|
||||
require.NotNil(t, updatedChannel.BannerInfo)
|
||||
require.Equal(t, "updated text", *updatedChannel.BannerInfo.Text)
|
||||
require.Equal(t, "#FFFFFF", *updatedChannel.BannerInfo.BackgroundColor)
|
||||
}
|
||||
|
||||
func testGetChannelUnread(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
@@ -7504,54 +7562,17 @@ func testMaterializedPublicChannels(t *testing.T, rctx request.CTX, ss store.Sto
|
||||
|
||||
// o3 is a public channel on the team that already existed in the PublicChannels table.
|
||||
o3 := model.Channel{
|
||||
Id: model.NewId(),
|
||||
TeamId: teamID,
|
||||
DisplayName: "Open Channel 3",
|
||||
Name: model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
_, execerr := s.GetMaster().NamedExec(`
|
||||
INSERT INTO
|
||||
PublicChannels(Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose)
|
||||
VALUES
|
||||
(:id, :deleteat, :teamid, :displayname, :name, :header, :purpose);
|
||||
`, map[string]any{
|
||||
"id": o3.Id,
|
||||
"deleteat": o3.DeleteAt,
|
||||
"teamid": o3.TeamId,
|
||||
"displayname": o3.DisplayName,
|
||||
"name": o3.Name,
|
||||
"header": o3.Header,
|
||||
"purpose": o3.Purpose,
|
||||
})
|
||||
require.NoError(t, execerr)
|
||||
_, nErr = ss.Channel().Save(rctx, &o3, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
o3.DisplayName = "Open Channel 3 - Modified"
|
||||
|
||||
_, execerr = s.GetMaster().NamedExec(`
|
||||
INSERT INTO
|
||||
Channels(Id, CreateAt, UpdateAt, DeleteAt, TeamId, Type, DisplayName, Name, Header, Purpose, LastPostAt, LastRootPostAt, TotalMsgCount, ExtraUpdateAt, CreatorId, TotalMsgCountRoot)
|
||||
VALUES
|
||||
(:id, :createat, :updateat, :deleteat, :teamid, :type, :displayname, :name, :header, :purpose, :lastpostat, :lastrootpostat, :totalmsgcount, :extraupdateat, :creatorid, 0);
|
||||
`, map[string]any{
|
||||
"id": o3.Id,
|
||||
"createat": o3.CreateAt,
|
||||
"updateat": o3.UpdateAt,
|
||||
"deleteat": o3.DeleteAt,
|
||||
"teamid": o3.TeamId,
|
||||
"type": o3.Type,
|
||||
"displayname": o3.DisplayName,
|
||||
"name": o3.Name,
|
||||
"header": o3.Header,
|
||||
"purpose": o3.Purpose,
|
||||
"lastpostat": o3.LastPostAt,
|
||||
"lastrootpostat": o3.LastRootPostAt,
|
||||
"totalmsgcount": o3.TotalMsgCount,
|
||||
"extraupdateat": o3.ExtraUpdateAt,
|
||||
"creatorid": o3.CreatorId,
|
||||
})
|
||||
require.NoError(t, execerr)
|
||||
_, err = ss.Channel().Update(rctx, &o3)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("verify o3 INSERT converted to UPDATE", func(t *testing.T) {
|
||||
channels, channelErr := ss.Channel().SearchInTeam(teamID, "", true)
|
||||
@@ -7570,7 +7591,7 @@ func testMaterializedPublicChannels(t *testing.T, rctx request.CTX, ss store.Sto
|
||||
_, nErr = ss.Channel().Save(rctx, &o4, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
_, execerr = s.GetMaster().Exec(`
|
||||
_, execerr := s.GetMaster().Exec(`
|
||||
DELETE FROM
|
||||
PublicChannels
|
||||
WHERE
|
||||
|
||||
Ссылка в новой задаче
Block a user