github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/store/sqlstore/status_store.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "database/sql" 8 "fmt" 9 "strings" 10 11 sq "github.com/Masterminds/squirrel" 12 "github.com/pkg/errors" 13 14 "github.com/mattermost/mattermost-server/v5/model" 15 "github.com/mattermost/mattermost-server/v5/store" 16 ) 17 18 type SqlStatusStore struct { 19 *SqlStore 20 } 21 22 func newSqlStatusStore(sqlStore *SqlStore) store.StatusStore { 23 s := &SqlStatusStore{sqlStore} 24 25 for _, db := range sqlStore.GetAllConns() { 26 table := db.AddTableWithName(model.Status{}, "Status").SetKeys(false, "UserId") 27 table.ColMap("UserId").SetMaxSize(26) 28 table.ColMap("Status").SetMaxSize(32) 29 table.ColMap("ActiveChannel").SetMaxSize(26) 30 } 31 32 return s 33 } 34 35 func (s SqlStatusStore) createIndexesIfNotExists() { 36 s.CreateIndexIfNotExists("idx_status_user_id", "Status", "UserId") 37 s.CreateIndexIfNotExists("idx_status_status", "Status", "Status") 38 } 39 40 func (s SqlStatusStore) SaveOrUpdate(status *model.Status) error { 41 if err := s.GetReplica().SelectOne(&model.Status{}, "SELECT * FROM Status WHERE UserId = :UserId", map[string]interface{}{"UserId": status.UserId}); err == nil { 42 if _, err := s.GetMaster().Update(status); err != nil { 43 return errors.Wrap(err, "failed to update Status") 44 } 45 } else { 46 if err := s.GetMaster().Insert(status); err != nil { 47 if !(strings.Contains(err.Error(), "for key 'PRIMARY'") && strings.Contains(err.Error(), "Duplicate entry")) { 48 return errors.Wrap(err, "failed in save Status") 49 } 50 } 51 } 52 return nil 53 } 54 55 func (s SqlStatusStore) Get(userId string) (*model.Status, error) { 56 var status model.Status 57 58 if err := s.GetReplica().SelectOne(&status, 59 `SELECT 60 * 61 FROM 62 Status 63 WHERE 64 UserId = :UserId`, map[string]interface{}{"UserId": userId}); err != nil { 65 if err == sql.ErrNoRows { 66 return nil, store.NewErrNotFound("Status", fmt.Sprintf("userId=%s", userId)) 67 } 68 return nil, errors.Wrapf(err, "failed to get Status with userId=%s", userId) 69 } 70 return &status, nil 71 } 72 73 func (s SqlStatusStore) GetByIds(userIds []string) ([]*model.Status, error) { 74 query := s.getQueryBuilder(). 75 Select("UserId, Status, Manual, LastActivityAt"). 76 From("Status"). 77 Where(sq.Eq{"UserId": userIds}) 78 queryString, args, err := query.ToSql() 79 if err != nil { 80 return nil, errors.Wrap(err, "status_tosql") 81 } 82 rows, err := s.GetReplica().Db.Query(queryString, args...) 83 if err != nil { 84 return nil, errors.Wrap(err, "failed to find Statuses") 85 } 86 var statuses []*model.Status 87 defer rows.Close() 88 for rows.Next() { 89 var status model.Status 90 if err = rows.Scan(&status.UserId, &status.Status, &status.Manual, &status.LastActivityAt); err != nil { 91 return nil, errors.Wrap(err, "unable to scan from rows") 92 } 93 statuses = append(statuses, &status) 94 } 95 if err = rows.Err(); err != nil { 96 return nil, errors.Wrap(err, "failed while iterating over rows") 97 } 98 99 return statuses, nil 100 } 101 102 func (s SqlStatusStore) ResetAll() error { 103 if _, err := s.GetMaster().Exec("UPDATE Status SET Status = :Status WHERE Manual = false", map[string]interface{}{"Status": model.STATUS_OFFLINE}); err != nil { 104 return errors.Wrap(err, "failed to update Statuses") 105 } 106 return nil 107 } 108 109 func (s SqlStatusStore) GetTotalActiveUsersCount() (int64, error) { 110 time := model.GetMillis() - (1000 * 60 * 60 * 24) 111 count, err := s.GetReplica().SelectInt("SELECT COUNT(UserId) FROM Status WHERE LastActivityAt > :Time", map[string]interface{}{"Time": time}) 112 if err != nil { 113 return count, errors.Wrap(err, "failed to count active users") 114 } 115 return count, nil 116 } 117 118 func (s SqlStatusStore) UpdateLastActivityAt(userId string, lastActivityAt int64) error { 119 if _, err := s.GetMaster().Exec("UPDATE Status SET LastActivityAt = :Time WHERE UserId = :UserId", map[string]interface{}{"UserId": userId, "Time": lastActivityAt}); err != nil { 120 return errors.Wrapf(err, "failed to update last activity for userId=%s", userId) 121 } 122 123 return nil 124 }