package data import ( "log" "fmt" "encoding/json" "elyby/minecraft-skinsystem/lib/services" "elyby/minecraft-skinsystem/lib/tools" "github.com/mediocregopher/radix.v2/redis" ) type SkinItem struct { UserId int `json:"userId"` Username string `json:"username"` SkinId int `json:"skinId"` Url string `json:"url"` Is1_8 bool `json:"is1_8"` IsSlim bool `json:"isSlim"` Hash string `json:"hash"` oldUsername string } const accountIdToUsernameKey string = "hash:username-to-account-id" func (s *SkinItem) Save() { str, _ := json.Marshal(s) pool, _ := services.RedisPool.Get() pool.Cmd("MULTI") // Если пользователь сменил ник, то мы должны удать его ключ if (s.oldUsername != "" && s.oldUsername != s.Username) { pool.Cmd("DEL", tools.BuildKey(s.oldUsername)) } // Если это новая запись или если пользователь сменил ник, то обновляем значение в хэш-таблице if (s.oldUsername != "" || s.oldUsername != s.Username) { pool.Cmd("HSET", accountIdToUsernameKey, s.UserId, s.Username) } pool.Cmd("SET", tools.BuildKey(s.Username), str) pool.Cmd("EXEC") s.oldUsername = s.Username } func (s *SkinItem) Delete() { if (s.oldUsername == "") { return; } pool, _ := services.RedisPool.Get() pool.Cmd("MULTI") pool.Cmd("DEL", tools.BuildKey(s.oldUsername)) pool.Cmd("HDEL", accountIdToUsernameKey, s.UserId) pool.Cmd("EXEC") } func FindSkinByUsername(username string) (SkinItem, error) { var record SkinItem; services.Logger.IncCounter("skins.storage.query", 1) response := services.RedisPool.Cmd("GET", tools.BuildKey(username)); if (response.IsType(redis.Nil)) { services.Logger.IncCounter("skins.storage.not_found", 1) return record, SkinNotFound{username} } result, err := response.Str() if (err == nil) { services.Logger.IncCounter("skins.storage.found", 1) decodeErr := json.Unmarshal([]byte(result), &record) if (decodeErr != nil) { log.Println("Cannot decode record data") } record.oldUsername = record.Username } return record, err } func FindSkinById(id int) (SkinItem, error) { response := services.RedisPool.Cmd("HGET", accountIdToUsernameKey, id); if (response.IsType(redis.Nil)) { return SkinItem{}, SkinNotFound{"unknown"} } username, _ := response.Str() return FindSkinByUsername(username) } type SkinNotFound struct { Who string } func (e SkinNotFound) Error() string { return fmt.Sprintf("Skin data not found. Required username \"%v\"", e.Who) }