github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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 }