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