diff options
Diffstat (limited to 'store/sql_post_store.go')
-rw-r--r-- | store/sql_post_store.go | 132 |
1 files changed, 109 insertions, 23 deletions
diff --git a/store/sql_post_store.go b/store/sql_post_store.go index 3460fca92..40dca9930 100644 --- a/store/sql_post_store.go +++ b/store/sql_post_store.go @@ -9,10 +9,8 @@ import ( "strconv" "strings" - l4g "code.google.com/p/log4go" "github.com/mattermost/platform/model" "github.com/mattermost/platform/utils" - "time" ) type SqlPostStore struct { @@ -32,7 +30,7 @@ func NewSqlPostStore(sqlStore *SqlStore) PostStore { table.ColMap("Message").SetMaxSize(4000) table.ColMap("Type").SetMaxSize(26) table.ColMap("Hashtags").SetMaxSize(1000) - table.ColMap("Props") + table.ColMap("Props").SetMaxSize(8000) table.ColMap("Filenames").SetMaxSize(4000) } @@ -40,21 +38,6 @@ func NewSqlPostStore(sqlStore *SqlStore) PostStore { } func (s SqlPostStore) UpgradeSchemaIfNeeded() { - colType := s.GetColumnDataType("Posts", "Props") - if colType != "text" { - - query := "ALTER TABLE Posts MODIFY COLUMN Props TEXT" - if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES { - query = "ALTER TABLE Posts ALTER COLUMN Props TYPE text" - } - - _, err := s.GetMaster().Exec(query) - if err != nil { - l4g.Critical("Failed to alter column Posts.Props to TEXT: " + err.Error()) - time.Sleep(time.Second) - panic("Failed to alter column Posts.Props to TEXT: " + err.Error()) - } - } } func (s SqlPostStore) CreateIndexesIfNotExists() { @@ -244,6 +227,99 @@ func (s SqlPostStore) Delete(postId string, time int64) StoreChannel { return storeChannel } +func (s SqlPostStore) permanentDelete(postId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + _, err := s.GetMaster().Exec("DELETE FROM Posts WHERE Id = :Id OR ParentId = :ParentId OR RootId = :RootId", map[string]interface{}{"Id": postId, "ParentId": postId, "RootId": postId}) + if err != nil { + result.Err = model.NewAppError("SqlPostStore.Delete", "We couldn't delete the post", "id="+postId+", err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlPostStore) permanentDeleteAllCommentByUser(userId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + _, err := s.GetMaster().Exec("DELETE FROM Posts WHERE UserId = :UserId AND RootId != ''", map[string]interface{}{"UserId": userId}) + if err != nil { + result.Err = model.NewAppError("SqlPostStore.permanentDeleteAllCommentByUser", "We couldn't delete the comments for user", "userId="+userId+", err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlPostStore) PermanentDeleteByUser(userId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + // First attempt to delete all the comments for a user + if r := <-s.permanentDeleteAllCommentByUser(userId); r.Err != nil { + result.Err = r.Err + storeChannel <- result + close(storeChannel) + return + } + + // Now attempt to delete all the root posts for a user. This will also + // delete all the comments for each post. + found := true + count := 0 + + for found { + var ids []string + _, err := s.GetMaster().Select(&ids, "SELECT Id FROM Posts WHERE UserId = :UserId LIMIT 1000", map[string]interface{}{"UserId": userId}) + if err != nil { + result.Err = model.NewAppError("SqlPostStore.PermanentDeleteByUser.select", "We couldn't select the posts to delete for the user", "userId="+userId+", err="+err.Error()) + storeChannel <- result + close(storeChannel) + return + } else { + found = false + for _, id := range ids { + found = true + if r := <-s.permanentDelete(id); r.Err != nil { + result.Err = r.Err + storeChannel <- result + close(storeChannel) + return + } + } + } + + // This is a fail safe, give up if more than 10K messages + count = count + 1 + if count >= 10 { + result.Err = model.NewAppError("SqlPostStore.PermanentDeleteByUser.toolarge", "We couldn't select the posts to delete for the user (too many), please re-run", "userId="+userId) + storeChannel <- result + close(storeChannel) + return + } + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + func (s SqlPostStore) GetPosts(channelId string, offset int, limit int) StoreChannel { storeChannel := make(StoreChannel) @@ -493,7 +569,8 @@ func (s SqlPostStore) getParentsPosts(channelId string, offset int, limit int) S AND DeleteAt = 0 ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset) q3 - WHERE q3.RootId != '') q1 ON q1.RootId = q2.Id + WHERE q3.RootId != '') q1 + ON q1.RootId = q2.Id OR q1.RootId = q2.RootId WHERE ChannelId = :ChannelId2 AND DeleteAt = 0 @@ -730,6 +807,7 @@ func (s SqlPostStore) AnalyticsUserCountsWithPostsByDay(teamId string) StoreChan WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId + AND Posts.CreateAt <= :EndTime ORDER BY Name DESC) AS t1 GROUP BY Name ORDER BY Name DESC @@ -748,17 +826,20 @@ func (s SqlPostStore) AnalyticsUserCountsWithPostsByDay(teamId string) StoreChan WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId + AND Posts.CreateAt <= :EndTime ORDER BY Name DESC) AS t1 GROUP BY Name ORDER BY Name DESC LIMIT 30` } + end := utils.MillisFromTime(utils.EndOfDay(utils.Yesterday())) + var rows model.AnalyticsRows _, err := s.GetReplica().Select( &rows, query, - map[string]interface{}{"TeamId": teamId, "Time": model.GetMillis() - 1000*60*60*24*31}) + map[string]interface{}{"TeamId": teamId, "EndTime": end}) if err != nil { result.Err = model.NewAppError("SqlPostStore.AnalyticsUserCountsWithPostsByDay", "We couldn't get user counts with posts", err.Error()) } else { @@ -790,7 +871,8 @@ func (s SqlPostStore) AnalyticsPostCountsByDay(teamId string) StoreChannel { WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId - AND Posts.CreateAt >:Time) AS t1 + AND Posts.CreateAt <= :EndTime + AND Posts.CreateAt >= :StartTime) AS t1 GROUP BY Name ORDER BY Name DESC LIMIT 30` @@ -808,17 +890,21 @@ func (s SqlPostStore) AnalyticsPostCountsByDay(teamId string) StoreChannel { WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId - AND Posts.CreateAt > :Time) AS t1 + AND Posts.CreateAt <= :EndTime + AND Posts.CreateAt >= :StartTime) AS t1 GROUP BY Name ORDER BY Name DESC LIMIT 30` } + end := utils.MillisFromTime(utils.EndOfDay(utils.Yesterday())) + start := utils.MillisFromTime(utils.StartOfDay(utils.Yesterday().AddDate(0, 0, -31))) + var rows model.AnalyticsRows _, err := s.GetReplica().Select( &rows, query, - map[string]interface{}{"TeamId": teamId, "Time": model.GetMillis() - 1000*60*60*24*31}) + map[string]interface{}{"TeamId": teamId, "StartTime": start, "EndTime": end}) if err != nil { result.Err = model.NewAppError("SqlPostStore.AnalyticsPostCountsByDay", "We couldn't get post counts by day", err.Error()) } else { |