github.com/mad-app/mattermost-server@v5.11.1+incompatible/store/sqlstore/emoji_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  	"fmt"
     9  	"net/http"
    10  
    11  	"github.com/mattermost/mattermost-server/einterfaces"
    12  	"github.com/mattermost/mattermost-server/model"
    13  	"github.com/mattermost/mattermost-server/store"
    14  	"github.com/mattermost/mattermost-server/utils"
    15  )
    16  
    17  const (
    18  	EMOJI_CACHE_SIZE = 5000
    19  	EMOJI_CACHE_SEC  = 1800 // 30 mins
    20  )
    21  
    22  var emojiCache *utils.Cache = utils.NewLru(EMOJI_CACHE_SIZE)
    23  
    24  type SqlEmojiStore struct {
    25  	SqlStore
    26  	metrics einterfaces.MetricsInterface
    27  }
    28  
    29  func NewSqlEmojiStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.EmojiStore {
    30  	s := &SqlEmojiStore{
    31  		SqlStore: sqlStore,
    32  		metrics:  metrics,
    33  	}
    34  
    35  	for _, db := range sqlStore.GetAllConns() {
    36  		table := db.AddTableWithName(model.Emoji{}, "Emoji").SetKeys(false, "Id")
    37  		table.ColMap("Id").SetMaxSize(26)
    38  		table.ColMap("CreatorId").SetMaxSize(26)
    39  		table.ColMap("Name").SetMaxSize(64)
    40  
    41  		table.SetUniqueTogether("Name", "DeleteAt")
    42  	}
    43  
    44  	return s
    45  }
    46  
    47  func (es SqlEmojiStore) CreateIndexesIfNotExists() {
    48  	es.CreateIndexIfNotExists("idx_emoji_update_at", "Emoji", "UpdateAt")
    49  	es.CreateIndexIfNotExists("idx_emoji_create_at", "Emoji", "CreateAt")
    50  	es.CreateIndexIfNotExists("idx_emoji_delete_at", "Emoji", "DeleteAt")
    51  	es.CreateIndexIfNotExists("idx_emoji_name", "Emoji", "Name")
    52  }
    53  
    54  func (es SqlEmojiStore) Save(emoji *model.Emoji) store.StoreChannel {
    55  	return store.Do(func(result *store.StoreResult) {
    56  		emoji.PreSave()
    57  		if result.Err = emoji.IsValid(); result.Err != nil {
    58  			return
    59  		}
    60  
    61  		if err := es.GetMaster().Insert(emoji); err != nil {
    62  			result.Err = model.NewAppError("SqlEmojiStore.Save", "store.sql_emoji.save.app_error", nil, "id="+emoji.Id+", "+err.Error(), http.StatusInternalServerError)
    63  		} else {
    64  			result.Data = emoji
    65  		}
    66  	})
    67  }
    68  
    69  func (es SqlEmojiStore) Get(id string, allowFromCache bool) store.StoreChannel {
    70  	return store.Do(func(result *store.StoreResult) {
    71  		if allowFromCache {
    72  			if cacheItem, ok := emojiCache.Get(id); ok {
    73  				if es.metrics != nil {
    74  					es.metrics.IncrementMemCacheHitCounter("Emoji")
    75  				}
    76  				result.Data = cacheItem.(*model.Emoji)
    77  				return
    78  			} else {
    79  				if es.metrics != nil {
    80  					es.metrics.IncrementMemCacheMissCounter("Emoji")
    81  				}
    82  			}
    83  		} else {
    84  			if es.metrics != nil {
    85  				es.metrics.IncrementMemCacheMissCounter("Emoji")
    86  			}
    87  		}
    88  
    89  		var emoji *model.Emoji
    90  
    91  		if err := es.GetReplica().SelectOne(&emoji,
    92  			`SELECT
    93  				*
    94  			FROM
    95  				Emoji
    96  			WHERE
    97  				Id = :Id
    98  				AND DeleteAt = 0`, map[string]interface{}{"Id": id}); err != nil {
    99  			result.Err = model.NewAppError("SqlEmojiStore.Get", "store.sql_emoji.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusNotFound)
   100  		} else {
   101  			result.Data = emoji
   102  
   103  			if allowFromCache {
   104  				emojiCache.AddWithExpiresInSecs(id, emoji, EMOJI_CACHE_SEC)
   105  			}
   106  		}
   107  	})
   108  }
   109  
   110  func (es SqlEmojiStore) GetByName(name string) store.StoreChannel {
   111  	return store.Do(func(result *store.StoreResult) {
   112  		var emoji *model.Emoji
   113  
   114  		if err := es.GetReplica().SelectOne(&emoji,
   115  			`SELECT
   116  				*
   117  			FROM
   118  				Emoji
   119  			WHERE
   120  				Name = :Name
   121  				AND DeleteAt = 0`, map[string]interface{}{"Name": name}); err != nil {
   122  			result.Err = model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError)
   123  			if err == sql.ErrNoRows {
   124  				result.Err.StatusCode = http.StatusNotFound
   125  			}
   126  		} else {
   127  			result.Data = emoji
   128  		}
   129  	})
   130  }
   131  
   132  func (es SqlEmojiStore) GetMultipleByName(names []string) store.StoreChannel {
   133  	return store.Do(func(result *store.StoreResult) {
   134  		keys, params := MapStringsToQueryParams(names, "Emoji")
   135  
   136  		var emojis []*model.Emoji
   137  
   138  		if _, err := es.GetReplica().Select(&emojis,
   139  			`SELECT
   140  				*
   141  			FROM
   142  				Emoji
   143  			WHERE
   144  				Name IN `+keys+`
   145  				AND DeleteAt = 0`, params); err != nil {
   146  			result.Err = model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get_by_name.app_error", nil, fmt.Sprintf("names=%v, %v", names, err.Error()), http.StatusInternalServerError)
   147  		} else {
   148  			result.Data = emojis
   149  		}
   150  	})
   151  }
   152  
   153  func (es SqlEmojiStore) GetList(offset, limit int, sort string) store.StoreChannel {
   154  	return store.Do(func(result *store.StoreResult) {
   155  		var emoji []*model.Emoji
   156  
   157  		query := "SELECT * FROM Emoji WHERE DeleteAt = 0"
   158  
   159  		if sort == model.EMOJI_SORT_BY_NAME {
   160  			query += " ORDER BY Name"
   161  		}
   162  
   163  		query += " LIMIT :Limit OFFSET :Offset"
   164  
   165  		if _, err := es.GetReplica().Select(&emoji, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
   166  			result.Err = model.NewAppError("SqlEmojiStore.GetList", "store.sql_emoji.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   167  		} else {
   168  			result.Data = emoji
   169  		}
   170  	})
   171  }
   172  
   173  func (es SqlEmojiStore) Delete(id string, time int64) store.StoreChannel {
   174  	return store.Do(func(result *store.StoreResult) {
   175  		if sqlResult, err := es.GetMaster().Exec(
   176  			`UPDATE
   177  				Emoji
   178  			SET
   179  				DeleteAt = :DeleteAt,
   180  				UpdateAt = :UpdateAt
   181  			WHERE
   182  				Id = :Id
   183  				AND DeleteAt = 0`, map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": id}); err != nil {
   184  			result.Err = model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.app_error", nil, "id="+id+", err="+err.Error(), http.StatusInternalServerError)
   185  		} else if rows, _ := sqlResult.RowsAffected(); rows == 0 {
   186  			result.Err = model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.no_results", nil, "id="+id+", err="+err.Error(), http.StatusBadRequest)
   187  		}
   188  
   189  		emojiCache.Remove(id)
   190  	})
   191  }
   192  
   193  func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) store.StoreChannel {
   194  	return store.Do(func(result *store.StoreResult) {
   195  		var emojis []*model.Emoji
   196  
   197  		term := ""
   198  		if !prefixOnly {
   199  			term = "%"
   200  		}
   201  
   202  		term += name + "%"
   203  
   204  		if _, err := es.GetReplica().Select(&emojis,
   205  			`SELECT
   206  				*
   207  			FROM
   208  				Emoji
   209  			WHERE
   210  				Name LIKE :Name
   211  				AND DeleteAt = 0
   212  				ORDER BY Name
   213  				LIMIT :Limit`, map[string]interface{}{"Name": term, "Limit": limit}); err != nil {
   214  			result.Err = model.NewAppError("SqlEmojiStore.Search", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError)
   215  		} else {
   216  			result.Data = emojis
   217  		}
   218  	})
   219  }