github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/sqlstore/emoji_store.go (about)

     1  // Copyright (c) 2015-present Xenia, 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/xzl8028/xenia-server/einterfaces"
    12  	"github.com/xzl8028/xenia-server/model"
    13  	"github.com/xzl8028/xenia-server/store"
    14  	"github.com/xzl8028/xenia-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) (*model.Emoji, *model.AppError) {
    55  	emoji.PreSave()
    56  	if err := emoji.IsValid(); err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	if err := es.GetMaster().Insert(emoji); err != nil {
    61  		return nil, model.NewAppError("SqlEmojiStore.Save", "store.sql_emoji.save.app_error", nil, "id="+emoji.Id+", "+err.Error(), http.StatusInternalServerError)
    62  	}
    63  	return emoji, nil
    64  }
    65  
    66  func (es SqlEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) {
    67  	if allowFromCache {
    68  		if cacheItem, ok := emojiCache.Get(id); ok {
    69  			if es.metrics != nil {
    70  				es.metrics.IncrementMemCacheHitCounter("Emoji")
    71  			}
    72  			return cacheItem.(*model.Emoji), nil
    73  		}
    74  		if es.metrics != nil {
    75  			es.metrics.IncrementMemCacheMissCounter("Emoji")
    76  		}
    77  	} else {
    78  		if es.metrics != nil {
    79  			es.metrics.IncrementMemCacheMissCounter("Emoji")
    80  		}
    81  	}
    82  
    83  	var emoji *model.Emoji
    84  
    85  	if err := es.GetReplica().SelectOne(&emoji,
    86  		`SELECT
    87  			*
    88  		FROM
    89  			Emoji
    90  		WHERE
    91  			Id = :Id
    92  			AND DeleteAt = 0`, map[string]interface{}{"Id": id}); err != nil {
    93  		return nil, model.NewAppError("SqlEmojiStore.Get", "store.sql_emoji.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusNotFound)
    94  	}
    95  
    96  	if allowFromCache {
    97  		emojiCache.AddWithExpiresInSecs(id, emoji, EMOJI_CACHE_SEC)
    98  	}
    99  
   100  	return emoji, nil
   101  }
   102  
   103  func (es SqlEmojiStore) GetByName(name string) (*model.Emoji, *model.AppError) {
   104  
   105  	var emoji *model.Emoji
   106  
   107  	if err := es.GetReplica().SelectOne(&emoji,
   108  		`SELECT
   109  			*
   110  		FROM
   111  			Emoji
   112  		WHERE
   113  			Name = :Name
   114  			AND DeleteAt = 0`, map[string]interface{}{"Name": name}); err != nil {
   115  
   116  		if err == sql.ErrNoRows {
   117  			return nil, model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusNotFound)
   118  		}
   119  
   120  		return nil, model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError)
   121  	}
   122  
   123  	return emoji, nil
   124  }
   125  
   126  func (es SqlEmojiStore) GetMultipleByName(names []string) store.StoreChannel {
   127  	return store.Do(func(result *store.StoreResult) {
   128  		keys, params := MapStringsToQueryParams(names, "Emoji")
   129  
   130  		var emojis []*model.Emoji
   131  
   132  		if _, err := es.GetReplica().Select(&emojis,
   133  			`SELECT
   134  				*
   135  			FROM
   136  				Emoji
   137  			WHERE
   138  				Name IN `+keys+`
   139  				AND DeleteAt = 0`, params); err != nil {
   140  			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)
   141  		} else {
   142  			result.Data = emojis
   143  		}
   144  	})
   145  }
   146  
   147  func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, *model.AppError) {
   148  	var emoji []*model.Emoji
   149  
   150  	query := "SELECT * FROM Emoji WHERE DeleteAt = 0"
   151  
   152  	if sort == model.EMOJI_SORT_BY_NAME {
   153  		query += " ORDER BY Name"
   154  	}
   155  
   156  	query += " LIMIT :Limit OFFSET :Offset"
   157  
   158  	if _, err := es.GetReplica().Select(&emoji, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
   159  		return nil, model.NewAppError("SqlEmojiStore.GetList", "store.sql_emoji.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   160  	}
   161  	return emoji, nil
   162  }
   163  
   164  func (es SqlEmojiStore) Delete(id string, time int64) *model.AppError {
   165  	if sqlResult, err := es.GetMaster().Exec(
   166  		`UPDATE
   167  			Emoji
   168  		SET
   169  			DeleteAt = :DeleteAt,
   170  			UpdateAt = :UpdateAt
   171  		WHERE
   172  			Id = :Id
   173  			AND DeleteAt = 0`, map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": id}); err != nil {
   174  		return model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.app_error", nil, "id="+id+", err="+err.Error(), http.StatusInternalServerError)
   175  	} else if rows, _ := sqlResult.RowsAffected(); rows == 0 {
   176  		return model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.no_results", nil, "id="+id+", err="+err.Error(), http.StatusBadRequest)
   177  	}
   178  
   179  	emojiCache.Remove(id)
   180  	return nil
   181  }
   182  
   183  func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) {
   184  	var emojis []*model.Emoji
   185  
   186  	term := ""
   187  	if !prefixOnly {
   188  		term = "%"
   189  	}
   190  
   191  	term += name + "%"
   192  
   193  	if _, err := es.GetReplica().Select(&emojis,
   194  		`SELECT
   195  			*
   196  		FROM
   197  			Emoji
   198  		WHERE
   199  			Name LIKE :Name
   200  			AND DeleteAt = 0
   201  			ORDER BY Name
   202  			LIMIT :Limit`, map[string]interface{}{"Name": term, "Limit": limit}); err != nil {
   203  		return nil, model.NewAppError("SqlEmojiStore.Search", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError)
   204  	}
   205  	return emojis, nil
   206  }