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  }