// adds a status to a user's follower's timelines func syndicateStatus(uid, sid, time string, c redis.Conn) (bool, error) { defer c.Close() // get all the followers user ids sorted by score // if this is exceptionally large we may want to do the syndication in stages r, err := redis.Values(c.Do("ZRANGEBYSCORE", "followers:"+uid, "-inf", "+inf")) if err != nil { return false, err } var followerSlice []string if err := redis.ScanSlice(r, &followerSlice); err != nil { return false, nil } // push the status in a single transaction c.Do("MULTI") for i := range followerSlice { c.Do("ZADD", "timeline:"+followerSlice[i], time, sid) } if _, err := c.Do("EXEC"); err != nil { return false, err } return true, nil }
func (logger *RedisLogger) FriendCount(userid string) (follows, followers, friends, blacklist int) { conn := logger.conn conn.Send("MULTI") conn.Send("SCARD", redisUserFollowPrefix+userid) conn.Send("SCARD", redisUserFollowerPrefix+userid) conn.Send("SCARD", redisUserBlacklistPrefix+userid) values, err := redis.Values(conn.Do("EXEC")) if err != nil { log.Println(err) return } counts := make([]int, 3) if err := redis.ScanSlice(values, &counts); err != nil { log.Println(err) return } follows = counts[0] followers = counts[1] blacklist = counts[2] friends = len(logger.Friends("friend", userid)) return }
func adminHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { uid := checkToken(r) if userCache["root"].Id == uid { rc := *(getRC()) defer rc.Close() res, _ := redis.Values(rc.Do("HGETALL", "order")) var arr []string redis.ScanSlice(res, &arr) responseJson := new(bytes.Buffer) responseJson.WriteString("[") for i := 0; i < len(arr); i += 2 { if i != 0 { responseJson.WriteString(",") } responseJson.WriteString(arr[i+1]) } responseJson.WriteString("]") response(&w, 200, responseJson.Bytes()) } else { responseInvalidToken(&w) } }
func (this *User) GetList(request *restful.Request, response *restful.Response) { var r resp pool := NewPool() c := pool.Get() keys := "user_list:*" var user User_format var user_array []User_format var list_user []string result, err := redis.Values(c.Do("KEYS", keys)) if result == nil || err != nil { r.Status = "fail" r.Errmsg = "no user" response.WriteEntity(r) return } redis.ScanSlice(result, &list_user) for _, value := range list_user { data, _ := GetService(value) json.Unmarshal(data, &user) user_array = append(user_array, user) } r.Status = "ok" r.Data = user_array response.WriteEntity(r) return }
func ExampleScanSlice() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Send("HMSET", "album:1", "title", "Red", "rating", 5) c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1) c.Send("HMSET", "album:3", "title", "Beat", "rating", 4) c.Send("LPUSH", "albums", "1") c.Send("LPUSH", "albums", "2") c.Send("LPUSH", "albums", "3") values, err := redis.Values(c.Do("SORT", "albums", "BY", "album:*->rating", "GET", "album:*->title", "GET", "album:*->rating")) if err != nil { fmt.Println(err) return } var albums []struct { Title string Rating int } if err := redis.ScanSlice(values, &albums); err != nil { fmt.Println(err) return } fmt.Printf("%v\n", albums) // Output: // [{Earthbound 1} {Beat 4} {Red 5}] }
func noteIDs(db redis.Conn) []int64 { var ids []int64 rawIDs, err := redis.Values(db.Do("LRANGE", "notable:notes", 0, -1)) check(err) redis.ScanSlice(rawIDs, &ids) return ids }
func (logger *RedisLogger) GetDisLB(start, stop int) []KV { values, _ := redis.Values(logger.conn.Do("ZREVRANGE", redisDisLeaderboard, start, stop, "WITHSCORES")) var s []KV if err := redis.ScanSlice(values, &s); err != nil { log.Println(err) return nil } return s }
func updateHosts() { values, err := redis.Values(conn.Do("SMEMBERS", "turn/hosts")) if err != nil { panic(err) } var hosts []string if err := redis.ScanSlice(values, &hosts); err != nil { panic(err) } turn.Hosts = hosts }
func (*RedisStore) Int64s(reply interface{}, err error) ([]int64, error) { var ints []int64 values, err := redis.Values(reply, err) if err != nil { return ints, err } if err := redis.ScanSlice(values, &ints); err != nil { return ints, err } return ints, nil }
func (a *app) ListSubject() (subs []string, err error) { reply, err := redis.Values(a.rpool.Get().Do("PUBSUB", "CHANNELS")) if err != nil { return } if len(reply) == 0 { return } if err = redis.ScanSlice(reply, &subs); err != nil { return } return }
func int64s(reply interface{}, err error) ([]int64, error) { if err != nil { return nil, slog.Wrap(err) } ints := []int64{} values, err := redis.Values(reply, err) if err != nil { return ints, slog.Wrap(err) } if err := redis.ScanSlice(values, &ints); err != nil { return ints, slog.Wrap(err) } return ints, nil }
func (logger *RedisLogger) zrange(key string, start, stop int, reverse bool) (kv []KV) { cmd := "ZRANGE" if reverse { cmd = "ZREVRANGE" } values, _ := redis.Values(logger.conn.Do(cmd, key, start, stop, "WITHSCORES")) if err := redis.ScanSlice(values, &kv); err != nil { log.Println(err) return nil } return }
// Returns logs stored in the list specified by logName. func ReadLogs(conn redis.Conn, logName string, limit int) (logs []string) { reply, err := redis.Values(conn.Do("LRANGE", logName, 0, limit)) if err != nil { log.Fatal(err) } if err := redis.ScanSlice(reply, &logs); err != nil { log.Fatal(err) } // can also use the following code to deal with sring reply // for len(reply) > 0 { // var logString string // reply, err = redis.Scan(reply, &logString) // log.Println(logString) // } return }
func printResponseReputationList(c *proto.Client, m *proto.Message, resp interface{}) { values, err := redis.Values(resp, nil) if err != nil { log.Print(err) return } var reps []struct { Name string Score int } err = redis.ScanSlice(values, &reps) for i, rep := range reps { c.PrivMsg(m.Receiver, "(%d) %-10s: %3d", i, rep.Name, rep.Score) } }
func TestScanSlice(t *testing.T) { for _, tt := range scanSliceTests { typ := reflect.ValueOf(tt.dest).Type() dest := reflect.New(typ) err := redis.ScanSlice(tt.src, dest.Interface(), tt.fieldNames...) if tt.ok != (err == nil) { t.Errorf("ScanSlice(%v, []%s, %v) returned error %v", tt.src, typ, tt.fieldNames, err) continue } if tt.ok && !reflect.DeepEqual(dest.Elem().Interface(), tt.dest) { t.Errorf("ScanSlice(src, []%s) returned %#v, want %#v", typ, dest.Elem().Interface(), tt.dest) } } }
func updateFoodCount() { values := make([]int, 0, foodNum) keys := make([]interface{}, 0, foodNum) for i := 1; i <= foodNum; i++ { keys = append(keys, i) } rc := *(getRC()) responseJson := new(bytes.Buffer) for { time.Sleep(time.Duration(16) * time.Millisecond) res, err := redis.Values(rc.Do("MGET", keys...)) if err != nil { rc.Close() rc = *(getRC()) continue } redis.ScanSlice(res, &values) responseJson.Reset() responseJson.WriteString("[") for i := 0; i < foodNum; i++ { id, _ := keys[i].(int) foodCount[id] = values[i] //foodJson := fmt.Sprintf("{\"id\":%d,\"price\":%d,\"stock\":%d}", id, foodPrice[id], foodCount[id]) if i != 0 { responseJson.WriteString(",") } //responseJson.WriteString(foodJson) responseJson.WriteString("{\"id\":") responseJson.WriteString(strconv.Itoa(id)) responseJson.WriteString(",\"price\":") responseJson.WriteString(strconv.Itoa(foodPrice[id])) responseJson.WriteString(",\"stock\":") responseJson.WriteString(strconv.Itoa(foodCount[id])) responseJson.WriteString("}") } responseJson.WriteString("]") foodListCache = responseJson.Bytes() } rc.Close() }
func (db *DB) GetUserTimeline(uid, page, count int) ([]int, error) { timeline := make([]int, page) c := db.Get() defer c.Close() // we use the page and count values to grab unique chunks of the timeline r, err := redis.Values(c.Do("ZREVRANGE", "timeline:"+strconv.Itoa(uid), strconv.Itoa((page-1)*count), strconv.Itoa(page*(count-1)))) if err != nil { return nil, err } if err := redis.ScanSlice(r, &timeline); err != nil { panic(err) } return timeline, nil }
// GetTriggerTags returns trigger tags func (connector *DbConnector) GetTriggerTags(triggerID string) ([]string, error) { c := connector.Pool.Get() defer c.Close() var tags []string values, err := redis.Values(c.Do("SMEMBERS", fmt.Sprintf("moira-trigger-tags:%s", triggerID))) if err != nil { return nil, fmt.Errorf("Failed to retrieve tags for trigger id %s: %s", triggerID, err.Error()) } if err := redis.ScanSlice(values, &tags); err != nil { return nil, fmt.Errorf("Failed to retrieve tags for trigger id %s: %s", triggerID, err.Error()) } if len(tags) == 0 { return nil, fmt.Errorf("No tags found for trigger id %s", triggerID) } return tags, nil }
func updateSecret() { values, err := redis.Values(conn.Do("KEYS", "turn/secret/*")) if err != nil { panic(err) } var keys []string if err := redis.ScanSlice(values, &keys); err != nil { panic(err) } if len(keys) == 0 { return } sort.Sort(sort.StringSlice(keys)) key := keys[0] item, err := redis.String(conn.Do("GET", key)) if err != nil { panic(err) } turn.Secret = item }
func (logger *RedisLogger) PV(date string) []KV { if len(date) == 0 { return nil } conn := logger.conn count, _ := redis.Int(conn.Do("ZCARD", redisStatPvPrefix+date)) values, err := redis.Values(conn.Do("ZREVRANGE", redisStatPvPrefix+date, 0, count, "WITHSCORES")) if err != nil { log.Println(err) return nil } var pvs []KV if err := redis.ScanSlice(values, &pvs); err != nil { log.Println(err) return nil } return pvs }
func (p *portalAPI) getAllKeys(email string, res http.ResponseWriter, req *http.Request) { keys, err := p.m.GetAllKeys(email) if err != nil { abort(res, 500, err.Error()) return } results := make([]keyWithQuota, len(keys)) if len(results) == 0 { finish(res, results) return } avgs := make([]float64, len(keys)) redisAvgKeys := make([]interface{}, len(keys)) for i, k := range keys { redisAvgKeys[i] = "quota:key:" + k.ID + ":avg" } r := p.a.redis.Get() rawAvgs, err := redis.Values(r.Do("MGET", redisAvgKeys...)) if err != nil { abort(res, 500, err.Error()) } if err = redis.ScanSlice(rawAvgs, &avgs); err != nil { abort(res, 500, err.Error()) } for i, k := range keys { q, ok := p.a.quotas[k.Quota] if !ok { q = p.a.quotas["default"] } kwq := keyWithQuota{Key: k, Quota: q, Avg: avgs[i]} results[i] = kwq } finish(res, results) }
func (logger *RedisLogger) zrevrank(key string, members ...string) (ranks []int) { conn := logger.conn if len(members) == 0 { return nil } conn.Send("MULTI") for _, member := range members { conn.Send("ZREVRANK", key, member) } values, err := redis.Values(conn.Do("EXEC")) if err != nil { log.Println(err) return nil } if err := redis.ScanSlice(values, &ranks); err != nil { log.Println(err) return nil } return }
func (logger *RedisLogger) zscores(key string, members ...string) (scores []int64) { conn := logger.conn if len(members) == 0 { return nil } conn.Send("MULTI") for _, member := range members { conn.Send("ZSCORE", key, member) } values, err := redis.Values(conn.Do("EXEC")) if err != nil { log.Println(err) return nil } if err := redis.ScanSlice(values, &scores); err != nil { log.Println(err) return nil } return }
func (db *Database) Query(q string) ([]Package, error) { terms := parseQuery(q) if len(terms) == 0 { return nil, nil } c := db.Pool.Get() defer c.Close() n, err := redis.Int(c.Do("INCR", "maxQueryId")) if err != nil { return nil, err } id := "tmp:query-" + strconv.Itoa(n) args := []interface{}{id} for _, term := range terms { args = append(args, "index:"+term) } c.Send("SINTERSTORE", args...) c.Send("SORT", id, "DESC", "BY", "nosort", "GET", "pkg:*->path", "GET", "pkg:*->synopsis", "GET", "pkg:*->score") c.Send("DEL", id) c.Flush() c.Receive() // SINTERSTORE values, err := redis.Values(c.Receive()) // SORT if err != nil { return nil, err } c.Receive() // DEL var queryResults []*queryResult if err := redis.ScanSlice(values, &queryResults, "Path", "Synopsis", "Score"); err != nil { return nil, err } for _, qr := range queryResults { c.Send("SCARD", "index:import:"+qr.Path) } c.Flush() for _, qr := range queryResults { importCount, err := redis.Int(c.Receive()) if err != nil { return nil, err } qr.Score *= math.Log(float64(10 + importCount)) if isStandardPackage(qr.Path) { if strings.HasSuffix(qr.Path, q) { // Big bump for exact match on standard package name. qr.Score *= 10000 } else { qr.Score *= 1.2 } } if q == path.Base(qr.Path) { qr.Score *= 1.1 } } sort.Sort(byScore(queryResults)) pkgs := make([]Package, len(queryResults)) for i, qr := range queryResults { pkgs[i].Path = qr.Path pkgs[i].Synopsis = qr.Synopsis } return pkgs, nil }
func postOrderHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { type inputData struct { CartId string `json:"cart_id"` } uid := checkToken(r) if uid != -1 { decoder := json.NewDecoder(r.Body) var input inputData err := decoder.Decode(&input) if err != nil { if err.Error() == "EOF" { responseEemptyRequest(&w) } else { responseMalformedJson(&w) } return } rc := *(getRC()) //defer rc.Close() rc.Send("HGET", "order", rTokenCache[uid]) rc.Send("HGETALL", "cart:"+input.CartId) rc.Flush() //oid, _ := redis.String(rc.Do("HGET", "order", rTokenCache[uid])) oid, _ := redis.String(rc.Receive()) if oid != "" { rc.Close() response(&w, 403, []byte(`{"code":"ORDER_OUT_OF_LIMIT","message":"每个用户只能下一单"}`)) } else { uh := input.CartId[0 : len(input.CartId)-9] cuid, isHave := tokenCache[uh] if isHave == false { rc.Close() response(&w, 404, []byte(`{"code":"CART_NOT_FOUND","message":"篮子不存在"}`)) } else if uid != cuid { rc.Close() response(&w, 401, []byte(`{"code":"NOT_AUTHORIZED_TO_ACCESS_CART","message":"无权限访问指定的篮子"}`)) } else { total := 0 itemsBuffer := new(bytes.Buffer) itemsBuffer.WriteString("{\"id\":\"") itemsBuffer.WriteString(rTokenCache[uid]) itemsBuffer.WriteString("\",\"user_id\":") itemsBuffer.WriteString(strconv.Itoa(uid)) itemsBuffer.WriteString(",\"items\":[") //res, _ := redis.Int64Map(rc.Do("HGETALL", "cart:" + input.CartId)) res, _ := redis.Int64Map(rc.Receive()) food_id := make([]interface{}, 0, 3) food_count := make([]int, 0, 3) var food_len int simple := true for k, v := range res { fid, _ := strconv.Atoi(k) food_id = append(food_id, fid) value := int(v) food_count = append(food_count, value) if foodCount[fid] < value { rc.Close() response(&w, 403, []byte(`{"code":"FOOD_OUT_OF_STOCK","message":"食物库存不足"}`)) return } // if itemsBuffer.Len() == 1 { // itemsBuffer.WriteString(fmt.Sprintf("{\"food_id\":%d,\"count\":%d}", fid, value)) // } else { // itemsBuffer.WriteString(fmt.Sprintf(",{\"food_id\":%d,\"count\":%d}", fid, value)) // } if total != 0 { itemsBuffer.WriteString(",") } itemsBuffer.WriteString("{\"food_id\":") itemsBuffer.WriteString(strconv.Itoa(fid)) itemsBuffer.WriteString(",\"count\":") itemsBuffer.WriteString(strconv.Itoa(value)) itemsBuffer.WriteString("}") total += foodPrice[fid] * value if foodCount[fid] < 100 { simple = false } } food_len = len(food_id) if simple { for i := 0; i < food_len; i++ { fid := food_id[i].(int) rc.Send("DECRBY", fid, food_count[i]) } // success itemsBuffer.WriteString("],\"total\":") itemsBuffer.WriteString(strconv.Itoa(total)) itemsBuffer.WriteString("}") orderToken := rTokenCache[uid] rc.Send("HSET", "order", orderToken, itemsBuffer.String()) rc.Flush() rc.Close() response(&w, 200, []byte("{\"id\":\""+orderToken+"\"}")) } else { for { rc.Do("WATCH", food_id...) counts := make([]int, 0, 3) fc, _ := redis.Values(rc.Do("MGET", food_id...)) redis.ScanSlice(fc, &counts) toRedis := make([]interface{}, 0, 6) for i := 0; i < food_len; i++ { counts[i] -= food_count[i] if counts[i] < 0 { rc.Do("UNWATCH", food_id...) rc.Close() response(&w, 403, []byte(`{"code":"FOOD_OUT_OF_STOCK","message":"食物库存不足"}`)) return } else { toRedis = append(toRedis, food_id[i], counts[i]) } } rc.Send("MULTI") rc.Send("MSET", toRedis...) queued, _ := rc.Do("EXEC") if queued != nil { break } } // success itemsBuffer.WriteString("],\"total\":") itemsBuffer.WriteString(strconv.Itoa(total)) itemsBuffer.WriteString("}") orderToken := rTokenCache[uid] rc.Do("HSET", "order", orderToken, itemsBuffer.String()) rc.Close() response(&w, 200, []byte("{\"id\":\""+orderToken+"\"}")) } } } } else { responseInvalidToken(&w) } }
// ZREVRANGEBYSCORE k start end func (db *RDB) ZRANGEBYSCORE(out interface{}, args ...interface{}) error { values, err := redis.Values(db.conn.Do("ZRANGEBYSCORE", args...)) redis.ScanSlice(values, out) return err }
// GetTagsSubscriptions returns all subscriptions for given tags list func (connector *DbConnector) GetTagsSubscriptions(tags []string) ([]SubscriptionData, error) { c := connector.Pool.Get() defer c.Close() log.Debug("Getting tags %v subscriptions", tags) tagKeys := make([]interface{}, 0, len(tags)) for _, tag := range tags { tagKeys = append(tagKeys, fmt.Sprintf("moira-tag-subscriptions:%s", tag)) } values, err := redis.Values(c.Do("SUNION", tagKeys...)) if err != nil { return nil, fmt.Errorf("Failed to retrieve subscriptions for tags %v: %s", tags, err.Error()) } var subscriptions []string if err := redis.ScanSlice(values, &subscriptions); err != nil { return nil, fmt.Errorf("Failed to retrieve subscriptions for tags %v: %s", tags, err.Error()) } if len(subscriptions) == 0 { log.Debug("No subscriptions found for tag set %v", tags) return make([]SubscriptionData, 0, 0), nil } var subscriptionsData []SubscriptionData for _, id := range subscriptions { sub, err := db.GetSubscription(id) if err != nil { continue } subscriptionsData = append(subscriptionsData, sub) } return subscriptionsData, nil }