From bf1fdf92c71df29ddb7b0e31a00e218863c1158c Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 13 Feb 2018 15:17:29 -0500 Subject: XYZ-110: Cherrypicking changes from release-4.7 to master (#8254) * Cherry-picking 7b2861de3a09cf00d00b0872cc537d54302c4bfa to master because enterprise/master has code in it that enterprise/release-4.7 does not, and I don't want enterprise/master to break the next time somebody merges enterprise/release-4.7 to enterprise/master * Renamed file to match existing scheme (cherry picked from commit 8c22c5c6c6f835a6e73faf19036bad2a51bb9127) --- app/channel_test.go | 20 +++++++++--------- model/channel_member_history.go | 4 ---- model/channel_member_history_result.go | 15 +++++++++++++ store/sqlstore/channel_member_history_store.go | 8 +++---- store/sqlstore/upgrade.go | 2 ++ store/storetest/channel_member_history_store.go | 28 ++++++++++++------------- 6 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 model/channel_member_history_result.go diff --git a/app/channel_test.go b/app/channel_test.go index d315fbae6..e4a0e4320 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -116,14 +116,14 @@ func TestJoinDefaultChannelsTownSquare(t *testing.T) { // figure out the initial number of users in town square townSquareChannelId := store.Must(th.App.Srv.Store.Channel().GetByName(th.BasicTeam.Id, "town-square", true)).(*model.Channel).Id - initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistory)) + initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult)) // create a new user that joins the default channels user := th.CreateUser() th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "") // there should be a ChannelMemberHistory record for the user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, initialNumTownSquareUsers+1) found := false @@ -142,14 +142,14 @@ func TestJoinDefaultChannelsOffTopic(t *testing.T) { // figure out the initial number of users in off-topic offTopicChannelId := store.Must(th.App.Srv.Store.Channel().GetByName(th.BasicTeam.Id, "off-topic", true)).(*model.Channel).Id - initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistory)) + initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult)) // create a new user that joins the default channels user := th.CreateUser() th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "") // there should be a ChannelMemberHistory record for the user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, initialNumTownSquareUsers+1) found := false @@ -170,7 +170,7 @@ func TestCreateChannelPublic(t *testing.T) { publicChannel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN) // there should be a ChannelMemberHistory record for the user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 1) assert.Equal(t, th.BasicUser.Id, histories[0].UserId) assert.Equal(t, publicChannel.Id, histories[0].ChannelId) @@ -184,7 +184,7 @@ func TestCreateChannelPrivate(t *testing.T) { privateChannel := th.createChannel(th.BasicTeam, model.CHANNEL_PRIVATE) // there should be a ChannelMemberHistory record for the user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, privateChannel.Id)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, privateChannel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 1) assert.Equal(t, th.BasicUser.Id, histories[0].UserId) assert.Equal(t, privateChannel.Id, histories[0].ChannelId) @@ -221,7 +221,7 @@ func TestCreateGroupChannel(t *testing.T) { t.Fatal("Failed to create group channel. Error: " + err.Message) } else { // there should be a ChannelMemberHistory record for each user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 3) channelMemberHistoryUserIds := make([]string, 0) @@ -253,7 +253,7 @@ func TestAddUserToChannel(t *testing.T) { } // there should be a ChannelMemberHistory record for the user - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 2) channelMemberHistoryUserIds := make([]string, 0) for _, history := range histories { @@ -269,7 +269,7 @@ func TestRemoveUserFromChannel(t *testing.T) { // a user creates a channel publicChannel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN) - histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory) + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 1) assert.Equal(t, th.BasicUser.Id, histories[0].UserId) assert.Equal(t, publicChannel.Id, histories[0].ChannelId) @@ -279,7 +279,7 @@ func TestRemoveUserFromChannel(t *testing.T) { if err := th.App.LeaveChannel(publicChannel.Id, th.BasicUser.Id); err != nil { t.Fatal("Failed to remove user from channel. Error: " + err.Message) } - histories = store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory) + histories = store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, histories, 1) assert.Equal(t, th.BasicUser.Id, histories[0].UserId) assert.Equal(t, publicChannel.Id, histories[0].ChannelId) diff --git a/model/channel_member_history.go b/model/channel_member_history.go index 47c59d54e..55435c320 100644 --- a/model/channel_member_history.go +++ b/model/channel_member_history.go @@ -8,8 +8,4 @@ type ChannelMemberHistory struct { UserId string JoinTime int64 LeaveTime *int64 - - // these two fields are never set in the database - when we SELECT, we join on Users to get them - UserEmail string `db:"Email"` - Username string } diff --git a/model/channel_member_history_result.go b/model/channel_member_history_result.go new file mode 100644 index 000000000..ed3e79639 --- /dev/null +++ b/model/channel_member_history_result.go @@ -0,0 +1,15 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +type ChannelMemberHistoryResult struct { + ChannelId string + UserId string + JoinTime int64 + LeaveTime *int64 + + // these two fields are never set in the database - when we SELECT, we join on Users to get them + UserEmail string `db:"Email"` + Username string +} diff --git a/store/sqlstore/channel_member_history_store.go b/store/sqlstore/channel_member_history_store.go index 0b86aac28..6fc78b514 100644 --- a/store/sqlstore/channel_member_history_store.go +++ b/store/sqlstore/channel_member_history_store.go @@ -106,7 +106,7 @@ func (s SqlChannelMemberHistoryStore) hasDataAtOrBefore(time int64) (bool, error } } -func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) { +func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistoryResult, error) { query := ` SELECT cmh.*, @@ -120,7 +120,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime ORDER BY cmh.JoinTime ASC` params := map[string]interface{}{"ChannelId": channelId, "StartTime": startTime, "EndTime": endTime} - var histories []*model.ChannelMemberHistory + var histories []*model.ChannelMemberHistoryResult if _, err := s.GetReplica().Select(&histories, query, params); err != nil { return nil, err } else { @@ -128,7 +128,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime } } -func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) { +func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistoryResult, error) { query := ` SELECT DISTINCT ch.ChannelId, @@ -140,7 +140,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64 WHERE ch.ChannelId = :ChannelId` params := map[string]interface{}{"ChannelId": channelId} - var histories []*model.ChannelMemberHistory + var histories []*model.ChannelMemberHistoryResult if _, err := s.GetReplica().Select(&histories, query, params); err != nil { return nil, err } else { diff --git a/store/sqlstore/upgrade.go b/store/sqlstore/upgrade.go index 56fdf9d6c..09f2c9160 100644 --- a/store/sqlstore/upgrade.go +++ b/store/sqlstore/upgrade.go @@ -346,6 +346,8 @@ func UpgradeDatabaseToVersion47(sqlStore SqlStore) { if shouldPerformUpgrade(sqlStore, VERSION_4_6_0, VERSION_4_7_0) { sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)") sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)") + sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email") + sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username") saveSchemaVersion(sqlStore, VERSION_4_7_0) } } diff --git a/store/storetest/channel_member_history_store.go b/store/storetest/channel_member_history_store.go index fa2e7a8fa..b79e84fd8 100644 --- a/store/storetest/channel_member_history_store.go +++ b/store/storetest/channel_member_history_store.go @@ -102,11 +102,11 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) { store.Must(ss.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, joinTime)) // case 1: user joins and leaves the channel before the export period begins - channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 0) // case 2: user joins the channel after the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -116,7 +116,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) { assert.Nil(t, channelMembers[0].LeaveTime) // case 3: user joins the channel before the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -129,7 +129,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) { store.Must(ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, leaveTime)) // case 4: user joins the channel before the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -139,7 +139,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) { assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime) // case 5: user joins the channel after the export period begins, and leaves the channel before the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -149,7 +149,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) { assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime) // case 6: user has joined and left the channel long before the export period begins - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 0) } @@ -195,7 +195,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { // the past, even though the time that they were actually in the channel doesn't necessarily overlap with the export period // case 1: user joins and leaves the channel before the export period begins - channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -205,7 +205,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { assert.Equal(t, joinTime-100, *channelMembers[0].LeaveTime) // case 2: user joins the channel after the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -215,7 +215,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime) // case 3: user joins the channel before the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -225,7 +225,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime) // case 4: user joins the channel before the export period begins, but has not yet left the channel when the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -235,7 +235,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { assert.Equal(t, leaveTime-100, *channelMembers[0].LeaveTime) // case 5: user joins the channel after the export period begins, and leaves the channel before the export period ends - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -245,7 +245,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) { assert.Equal(t, leaveTime+100, *channelMembers[0].LeaveTime) // case 6: user has joined and left the channel long before the export period begins - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, user.Id, channelMembers[0].UserId) @@ -290,7 +290,7 @@ func testPermanentDeleteBatch(t *testing.T, ss store.Store) { store.Must(ss.ChannelMemberHistory().LogJoinEvent(user2.Id, channel.Id, joinTime)) // in between the join time and the leave time, both users were members of the channel - channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 2) // the permanent delete should delete at least one record @@ -298,7 +298,7 @@ func testPermanentDeleteBatch(t *testing.T, ss store.Store) { assert.NotEqual(t, int64(0), rowsDeleted) // after the delete, there should be one less member in the channel - channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistory) + channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistoryResult) assert.Len(t, channelMembers, 1) assert.Equal(t, user2.Id, channelMembers[0].UserId) } -- cgit v1.2.3-1-g7c22