github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/sqlstore/status_store.go (about) 1 // Copyright (c) 2016-present Xenia, 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/xzl8028/xenia-server/model" 13 "github.com/xzl8028/xenia-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) *model.AppError { 43 if err := s.GetReplica().SelectOne(&model.Status{}, "SELECT * FROM Status WHERE UserId = :UserId", map[string]interface{}{"UserId": status.UserId}); err == nil { 44 if _, err := s.GetMaster().Update(status); err != nil { 45 return model.NewAppError("SqlStatusStore.SaveOrUpdate", "store.sql_status.update.app_error", nil, err.Error(), http.StatusInternalServerError) 46 } 47 } else { 48 if err := s.GetMaster().Insert(status); err != nil { 49 if !(strings.Contains(err.Error(), "for key 'PRIMARY'") && strings.Contains(err.Error(), "Duplicate entry")) { 50 return model.NewAppError("SqlStatusStore.SaveOrUpdate", "store.sql_status.save.app_error", nil, err.Error(), http.StatusInternalServerError) 51 } 52 } 53 } 54 return nil 55 } 56 57 func (s SqlStatusStore) Get(userId string) (*model.Status, *model.AppError) { 58 var status model.Status 59 60 if err := s.GetReplica().SelectOne(&status, 61 `SELECT 62 * 63 FROM 64 Status 65 WHERE 66 UserId = :UserId`, map[string]interface{}{"UserId": userId}); err != nil { 67 if err == sql.ErrNoRows { 68 return nil, model.NewAppError("SqlStatusStore.Get", MISSING_STATUS_ERROR, nil, err.Error(), http.StatusNotFound) 69 } 70 return nil, model.NewAppError("SqlStatusStore.Get", "store.sql_status.get.app_error", nil, err.Error(), http.StatusInternalServerError) 71 } 72 return &status, nil 73 } 74 75 func (s SqlStatusStore) GetByIds(userIds []string) ([]*model.Status, *model.AppError) { 76 props := make(map[string]interface{}) 77 idQuery := "" 78 79 for index, userId := range userIds { 80 if len(idQuery) > 0 { 81 idQuery += ", " 82 } 83 84 props["userId"+strconv.Itoa(index)] = userId 85 idQuery += ":userId" + strconv.Itoa(index) 86 } 87 88 var statuses []*model.Status 89 if _, err := s.GetReplica().Select(&statuses, "SELECT * FROM Status WHERE UserId IN ("+idQuery+")", props); err != nil { 90 return nil, model.NewAppError("SqlStatusStore.GetByIds", "store.sql_status.get.app_error", nil, err.Error(), http.StatusInternalServerError) 91 } 92 return statuses, nil 93 } 94 95 func (s SqlStatusStore) GetOnlineAway() ([]*model.Status, *model.AppError) { 96 var statuses []*model.Status 97 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 { 98 return nil, model.NewAppError("SqlStatusStore.GetOnlineAway", "store.sql_status.get_online_away.app_error", nil, err.Error(), http.StatusInternalServerError) 99 } 100 return statuses, nil 101 } 102 103 func (s SqlStatusStore) GetOnline() ([]*model.Status, *model.AppError) { 104 var statuses []*model.Status 105 if _, err := s.GetReplica().Select(&statuses, "SELECT * FROM Status WHERE Status = :Online", map[string]interface{}{"Online": model.STATUS_ONLINE}); err != nil { 106 return nil, model.NewAppError("SqlStatusStore.GetOnline", "store.sql_status.get_online.app_error", nil, err.Error(), http.StatusInternalServerError) 107 } 108 return statuses, nil 109 } 110 111 func (s SqlStatusStore) GetAllFromTeam(teamId string) ([]*model.Status, *model.AppError) { 112 var statuses []*model.Status 113 if _, err := s.GetReplica().Select(&statuses, 114 `SELECT s.* FROM Status AS s INNER JOIN 115 TeamMembers AS tm ON tm.TeamId=:TeamId AND s.UserId=tm.UserId`, map[string]interface{}{"TeamId": teamId}); err != nil { 116 return nil, model.NewAppError("SqlStatusStore.GetAllFromTeam", "store.sql_status.get_team_statuses.app_error", nil, err.Error(), http.StatusInternalServerError) 117 } 118 return statuses, nil 119 } 120 121 func (s SqlStatusStore) ResetAll() *model.AppError { 122 if _, err := s.GetMaster().Exec("UPDATE Status SET Status = :Status WHERE Manual = false", map[string]interface{}{"Status": model.STATUS_OFFLINE}); err != nil { 123 return model.NewAppError("SqlStatusStore.ResetAll", "store.sql_status.reset_all.app_error", nil, "", http.StatusInternalServerError) 124 } 125 return nil 126 } 127 128 func (s SqlStatusStore) GetTotalActiveUsersCount() (int64, *model.AppError) { 129 time := model.GetMillis() - (1000 * 60 * 60 * 24) 130 count, err := s.GetReplica().SelectInt("SELECT COUNT(UserId) FROM Status WHERE LastActivityAt > :Time", map[string]interface{}{"Time": time}) 131 if err != nil { 132 return count, model.NewAppError("SqlStatusStore.GetTotalActiveUsersCount", "store.sql_status.get_total_active_users_count.app_error", nil, err.Error(), http.StatusInternalServerError) 133 } 134 return count, nil 135 } 136 137 func (s SqlStatusStore) UpdateLastActivityAt(userId string, lastActivityAt int64) store.StoreChannel { 138 return store.Do(func(result *store.StoreResult) { 139 if _, err := s.GetMaster().Exec("UPDATE Status SET LastActivityAt = :Time WHERE UserId = :UserId", map[string]interface{}{"UserId": userId, "Time": lastActivityAt}); err != nil { 140 result.Err = model.NewAppError("SqlStatusStore.UpdateLastActivityAt", "store.sql_status.update_last_activity_at.app_error", nil, "", http.StatusInternalServerError) 141 } 142 }) 143 }