github.com/mad-app/mattermost-server@v5.11.1+incompatible/store/sqlstore/status_store.go (about) 1 // Copyright (c) 2016-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 "strconv" 10 "strings" 11 12 "github.com/mattermost/mattermost-server/model" 13 "github.com/mattermost/mattermost-server/store" 14 ) 15 16 const ( 17 MISSING_STATUS_ERROR = "store.sql_status.get.missing.app_error" 18 ) 19 20 type SqlStatusStore struct { 21 SqlStore 22 } 23 24 func NewSqlStatusStore(sqlStore SqlStore) store.StatusStore { 25 s := &SqlStatusStore{sqlStore} 26 27 for _, db := range sqlStore.GetAllConns() { 28 table := db.AddTableWithName(model.Status{}, "Status").SetKeys(false, "UserId") 29 table.ColMap("UserId").SetMaxSize(26) 30 table.ColMap("Status").SetMaxSize(32) 31 table.ColMap("ActiveChannel").SetMaxSize(26) 32 } 33 34 return s 35 } 36 37 func (s SqlStatusStore) CreateIndexesIfNotExists() { 38 s.CreateIndexIfNotExists("idx_status_user_id", "Status", "UserId") 39 s.CreateIndexIfNotExists("idx_status_status", "Status", "Status") 40 } 41 42 func (s SqlStatusStore) SaveOrUpdate(status *model.Status) store.StoreChannel { 43 return store.Do(func(result *store.StoreResult) { 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 result.Err = 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 result.Err = model.NewAppError("SqlStatusStore.SaveOrUpdate", "store.sql_status.save.app_error", nil, err.Error(), http.StatusInternalServerError) 52 } 53 } 54 } 55 }) 56 } 57 58 func (s SqlStatusStore) Get(userId string) store.StoreChannel { 59 return store.Do(func(result *store.StoreResult) { 60 var status model.Status 61 62 if err := s.GetReplica().SelectOne(&status, 63 `SELECT 64 * 65 FROM 66 Status 67 WHERE 68 UserId = :UserId`, map[string]interface{}{"UserId": userId}); err != nil { 69 if err == sql.ErrNoRows { 70 result.Err = model.NewAppError("SqlStatusStore.Get", MISSING_STATUS_ERROR, nil, err.Error(), http.StatusNotFound) 71 } else { 72 result.Err = model.NewAppError("SqlStatusStore.Get", "store.sql_status.get.app_error", nil, err.Error(), http.StatusInternalServerError) 73 } 74 } else { 75 result.Data = &status 76 } 77 }) 78 } 79 80 func (s SqlStatusStore) GetByIds(userIds []string) store.StoreChannel { 81 return store.Do(func(result *store.StoreResult) { 82 props := make(map[string]interface{}) 83 idQuery := "" 84 85 for index, userId := range userIds { 86 if len(idQuery) > 0 { 87 idQuery += ", " 88 } 89 90 props["userId"+strconv.Itoa(index)] = userId 91 idQuery += ":userId" + strconv.Itoa(index) 92 } 93 94 var statuses []*model.Status 95 if _, err := s.GetReplica().Select(&statuses, "SELECT * FROM Status WHERE UserId IN ("+idQuery+")", props); err != nil { 96 result.Err = model.NewAppError("SqlStatusStore.GetByIds", "store.sql_status.get.app_error", nil, err.Error(), http.StatusInternalServerError) 97 } else { 98 result.Data = statuses 99 } 100 }) 101 } 102 103 func (s SqlStatusStore) GetOnlineAway() store.StoreChannel { 104 return store.Do(func(result *store.StoreResult) { 105 var statuses []*model.Status 106 if _, err := s.GetReplica().Select(&statuses, "SELECT * FROM Status WHERE Status = :Online OR Status = :Away LIMIT 300", map[string]interface{}{"Online": model.STATUS_ONLINE, "Away": model.STATUS_AWAY}); err != nil { 107 result.Err = model.NewAppError("SqlStatusStore.GetOnlineAway", "store.sql_status.get_online_away.app_error", nil, err.Error(), http.StatusInternalServerError) 108 } else { 109 result.Data = statuses 110 } 111 }) 112 } 113 114 func (s SqlStatusStore) GetOnline() store.StoreChannel { 115 return store.Do(func(result *store.StoreResult) { 116 var statuses []*model.Status 117 if _, err := s.GetReplica().Select(&statuses, "SELECT * FROM Status WHERE Status = :Online", map[string]interface{}{"Online": model.STATUS_ONLINE}); err != nil { 118 result.Err = model.NewAppError("SqlStatusStore.GetOnline", "store.sql_status.get_online.app_error", nil, err.Error(), http.StatusInternalServerError) 119 } else { 120 result.Data = statuses 121 } 122 }) 123 } 124 125 func (s SqlStatusStore) GetAllFromTeam(teamId string) store.StoreChannel { 126 return store.Do(func(result *store.StoreResult) { 127 var statuses []*model.Status 128 if _, err := s.GetReplica().Select(&statuses, 129 `SELECT s.* FROM Status AS s INNER JOIN 130 TeamMembers AS tm ON tm.TeamId=:TeamId AND s.UserId=tm.UserId`, map[string]interface{}{"TeamId": teamId}); err != nil { 131 result.Err = model.NewAppError("SqlStatusStore.GetAllFromTeam", "store.sql_status.get_team_statuses.app_error", nil, err.Error(), http.StatusInternalServerError) 132 } else { 133 result.Data = statuses 134 } 135 }) 136 } 137 138 func (s SqlStatusStore) ResetAll() store.StoreChannel { 139 return store.Do(func(result *store.StoreResult) { 140 if _, err := s.GetMaster().Exec("UPDATE Status SET Status = :Status WHERE Manual = false", map[string]interface{}{"Status": model.STATUS_OFFLINE}); err != nil { 141 result.Err = model.NewAppError("SqlStatusStore.ResetAll", "store.sql_status.reset_all.app_error", nil, "", http.StatusInternalServerError) 142 } 143 }) 144 } 145 146 func (s SqlStatusStore) GetTotalActiveUsersCount() store.StoreChannel { 147 return store.Do(func(result *store.StoreResult) { 148 time := model.GetMillis() - (1000 * 60 * 60 * 24) 149 150 if count, err := s.GetReplica().SelectInt("SELECT COUNT(UserId) FROM Status WHERE LastActivityAt > :Time", map[string]interface{}{"Time": time}); err != nil { 151 result.Err = model.NewAppError("SqlStatusStore.GetTotalActiveUsersCount", "store.sql_status.get_total_active_users_count.app_error", nil, err.Error(), http.StatusInternalServerError) 152 } else { 153 result.Data = count 154 } 155 }) 156 } 157 158 func (s SqlStatusStore) UpdateLastActivityAt(userId string, lastActivityAt int64) store.StoreChannel { 159 return store.Do(func(result *store.StoreResult) { 160 if _, err := s.GetMaster().Exec("UPDATE Status SET LastActivityAt = :Time WHERE UserId = :UserId", map[string]interface{}{"UserId": userId, "Time": lastActivityAt}); err != nil { 161 result.Err = model.NewAppError("SqlStatusStore.UpdateLastActivityAt", "store.sql_status.update_last_activity_at.app_error", nil, "", http.StatusInternalServerError) 162 } 163 }) 164 }