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  }