github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/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 "net/http" 9 "strings" 10 11 sq "github.com/Masterminds/squirrel" 12 13 "github.com/mattermost/mattermost-server/v5/model" 14 "github.com/mattermost/mattermost-server/v5/store" 15 ) 16 17 const ( 18 MISSING_STATUS_ERROR = "store.sql_status.get.missing.app_error" 19 ) 20 21 type SqlStatusStore struct { 22 SqlStore 23 } 24 25 func newSqlStatusStore(sqlStore SqlStore) store.StatusStore { 26 s := &SqlStatusStore{sqlStore} 27 28 for _, db := range sqlStore.GetAllConns() { 29 table := db.AddTableWithName(model.Status{}, "Status").SetKeys(false, "UserId") 30 table.ColMap("UserId").SetMaxSize(26) 31 table.ColMap("Status").SetMaxSize(32) 32 table.ColMap("ActiveChannel").SetMaxSize(26) 33 } 34 35 return s 36 } 37 38 func (s SqlStatusStore) createIndexesIfNotExists() { 39 s.CreateIndexIfNotExists("idx_status_user_id", "Status", "UserId") 40 s.CreateIndexIfNotExists("idx_status_status", "Status", "Status") 41 } 42 43 func (s SqlStatusStore) SaveOrUpdate(status *model.Status) *model.AppError { 44 if err := s.GetReplica().SelectOne(&model.Status{}, "SELECT * FROM Status WHERE UserId = :UserId", map[string]interface{}{"UserId": status.UserId}); err == nil { 45 if _, err := s.GetMaster().Update(status); err != nil { 46 return model.NewAppError("SqlStatusStore.SaveOrUpdate", "store.sql_status.update.app_error", nil, err.Error(), http.StatusInternalServerError) 47 } 48 } else { 49 if err := s.GetMaster().Insert(status); err != nil { 50 if !(strings.Contains(err.Error(), "for key 'PRIMARY'") && strings.Contains(err.Error(), "Duplicate entry")) { 51 return model.NewAppError("SqlStatusStore.SaveOrUpdate", "store.sql_status.save.app_error", nil, err.Error(), http.StatusInternalServerError) 52 } 53 } 54 } 55 return nil 56 } 57 58 func (s SqlStatusStore) Get(userId string) (*model.Status, *model.AppError) { 59 var status model.Status 60 61 if err := s.GetReplica().SelectOne(&status, 62 `SELECT 63 * 64 FROM 65 Status 66 WHERE 67 UserId = :UserId`, map[string]interface{}{"UserId": userId}); err != nil { 68 if err == sql.ErrNoRows { 69 return nil, model.NewAppError("SqlStatusStore.Get", MISSING_STATUS_ERROR, nil, err.Error(), http.StatusNotFound) 70 } 71 return nil, model.NewAppError("SqlStatusStore.Get", "store.sql_status.get.app_error", nil, err.Error(), http.StatusInternalServerError) 72 } 73 return &status, nil 74 } 75 76 func (s SqlStatusStore) GetByIds(userIds []string) ([]*model.Status, *model.AppError) { 77 78 failure := func(err error) *model.AppError { 79 return model.NewAppError( 80 "SqlStatusStore.GetByIds", 81 "store.sql_status.get.app_error", 82 nil, 83 err.Error(), 84 http.StatusInternalServerError, 85 ) 86 } 87 88 query := s.getQueryBuilder(). 89 Select("UserId, Status, Manual, LastActivityAt"). 90 From("Status"). 91 Where(sq.Eq{"UserId": userIds}) 92 queryString, args, err := query.ToSql() 93 if err != nil { 94 return nil, failure(err) 95 } 96 rows, err := s.GetReplica().Db.Query(queryString, args...) 97 if err != nil { 98 return nil, failure(err) 99 } 100 var statuses []*model.Status 101 defer rows.Close() 102 for rows.Next() { 103 var status model.Status 104 if err = rows.Scan(&status.UserId, &status.Status, &status.Manual, &status.LastActivityAt); err != nil { 105 return nil, failure(err) 106 } 107 statuses = append(statuses, &status) 108 } 109 if err = rows.Err(); err != nil { 110 return nil, failure(err) 111 } 112 113 return statuses, nil 114 } 115 116 func (s SqlStatusStore) ResetAll() *model.AppError { 117 if _, err := s.GetMaster().Exec("UPDATE Status SET Status = :Status WHERE Manual = false", map[string]interface{}{"Status": model.STATUS_OFFLINE}); err != nil { 118 return model.NewAppError("SqlStatusStore.ResetAll", "store.sql_status.reset_all.app_error", nil, "", http.StatusInternalServerError) 119 } 120 return nil 121 } 122 123 func (s SqlStatusStore) GetTotalActiveUsersCount() (int64, *model.AppError) { 124 time := model.GetMillis() - (1000 * 60 * 60 * 24) 125 count, err := s.GetReplica().SelectInt("SELECT COUNT(UserId) FROM Status WHERE LastActivityAt > :Time", map[string]interface{}{"Time": time}) 126 if err != nil { 127 return count, model.NewAppError("SqlStatusStore.GetTotalActiveUsersCount", "store.sql_status.get_total_active_users_count.app_error", nil, err.Error(), http.StatusInternalServerError) 128 } 129 return count, nil 130 } 131 132 func (s SqlStatusStore) UpdateLastActivityAt(userId string, lastActivityAt int64) *model.AppError { 133 if _, err := s.GetMaster().Exec("UPDATE Status SET LastActivityAt = :Time WHERE UserId = :UserId", map[string]interface{}{"UserId": userId, "Time": lastActivityAt}); err != nil { 134 return model.NewAppError("SqlStatusStore.UpdateLastActivityAt", "store.sql_status.update_last_activity_at.app_error", nil, "", http.StatusInternalServerError) 135 } 136 137 return nil 138 }