func init() { store.DefaultDBManager.AddFuncWithSideEffects("del", func(db *store.DB, args []string) string { del_count := 0 for _, v := range args { ok := db.StoreDel(v) if ok { del_count += 1 } } return reply.IntReply(del_count) }) store.DefaultDBManager.AddFuncWithSideEffects("expire", func(db *store.DB, args []string) string { _, ok, _ := db.StoreGet(args[0], data.Any) if ok { millis := store.Milliseconds() expires, err := strconv.Atoi(args[1]) if err != nil { return reply.IntReply(0) } else { db.ExpiryRecord[args[0]] = millis + uint64(expires*1000) return reply.IntReply(1) } } return reply.IntReply(0) }) store.DefaultDBManager.AddFuncWithSideEffects("pexpire", func(db *store.DB, args []string) string { _, ok, _ := db.StoreGet(args[0], data.Any) if ok { millis := store.Milliseconds() expires, err := strconv.Atoi(args[1]) if err != nil { return reply.IntReply(0) } else { db.ExpiryRecord[args[0]] = millis + uint64(expires) return reply.IntReply(1) } } return reply.IntReply(0) }) store.DefaultDBManager.AddFunc("ttl", func(db *store.DB, args []string) string { _, ok, _ := db.StoreGet(args[0], data.Any) if !ok { return reply.IntReply(-2) } time, ok := db.ExpiryRecord[args[0]] millis := store.Milliseconds() if ok { if time == 0 { return reply.IntReply(-1) } else if time < millis { db.StoreDel(args[0]) return reply.IntReply(-2) } else { return reply.IntReply(int((time - millis) / 1000)) } } else { return reply.IntReply(-1) } }) store.DefaultDBManager.AddFunc("pttl", func(db *store.DB, args []string) string { _, ok, _ := db.StoreGet(args[0], data.Any) if !ok { return reply.IntReply(-2) } time, ok := db.ExpiryRecord[args[0]] millis := store.Milliseconds() if ok { if time == 0 { return reply.IntReply(-1) } else if time < millis { db.StoreDel(args[0]) return reply.IntReply(-2) } else { return reply.IntReply(int(time - millis)) } } else { return reply.IntReply(-1) } }) store.DefaultDBManager.AddFunc("exists", func(db *store.DB, args []string) string { _, ok, _ := db.StoreGet(args[0], data.Any) if ok { return reply.IntReply(1) } return reply.IntReply(0) }) store.DefaultDBManager.AddFunc("dump", func(db *store.DB, args []string) string { bytes_rep, ok := db.StoreDump(args[0]) fmt.Println(bytes_rep) str_rep := string(bytes_rep) if ok { return reply.BulkReply(str_rep) } else { return reply.NilReply } }) store.DefaultDBManager.AddFuncWithSideEffects("restore", func(db *store.DB, args []string) string { unquoted_data, _ := strconv.Unquote(args[1]) fmt.Println(unquoted_data) bytes_rep := []byte(unquoted_data) ok := db.StoreLoad(args[0], bytes_rep) if ok { return reply.OKReply } else { return reply.NilReply } }) store.DefaultDBManager.AddFunc("type", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], data.Any) if ok { return reply.IntReply(int(elem.Type())) } else { return reply.NilReply } }) store.DefaultDBManager.AddFunc("keys", func(db *store.DB, args []string) string { keys := db.StoreKeysMatch(args[0]) var writer reply.MultiBulkWriter writer.WriteCount(len(keys)) for _, key := range keys { writer.WriteString(key) } return writer.String() }) store.DefaultDBManager.AddFunc("randomkey", func(db *store.DB, args []string) string { for key, _ := range db.Store { return reply.BulkReply(key) } return reply.NilReply }) store.DefaultDBManager.AddFunc("ping", func(db *store.DB, args []string) string { return reply.BulkReply("PONG") }) }
func init() { store.RegisterStoreType(StringType) store.DefaultDBManager.AddFuncWithSideEffects("append", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) if ok { str, _ := elem.Value.(string) str += args[1] elem.Value = str return reply.IntReply(len(str)) } else { db.StoreSet(args[0], &data.Entry{args[1], StringType}) return reply.IntReply(len(args[1])) } }) bitCount := []uint8{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8} store.DefaultDBManager.AddFuncWithSideEffects("bitcount", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) if ok { byte_arr, _ := elem.Value.([]byte) c := 0 for _, c := range byte_arr { c += bitCount[c] } return reply.IntReply(c) } else { return reply.IntReply(0) } }) store.DefaultDBManager.AddFuncWithSideEffects("decr", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) var num int if ok { str, _ := elem.Value.(string) num, err := strconv.Atoi(str) if err != nil { panic(err) } num -= 1 elem.Value = fmt.Sprintf("%d", num) } else { num = -1 db.StoreSet(args[0], &data.Entry{"-1", StringType}) } return reply.IntReply(num) }) store.DefaultDBManager.AddFuncWithSideEffects("decrby", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) var num int decrby, err := strconv.Atoi(args[1]) if err != nil { panic(err) } if ok { str, _ := elem.Value.(string) num, err := strconv.Atoi(str) if err != nil { panic(err) } num -= decrby elem.Value = fmt.Sprintf("%d", num) } else { str := fmt.Sprintf("-%d", decrby) db.StoreSet(args[0], &data.Entry{str, StringType}) } println(num) return reply.IntReply(num) }) store.DefaultDBManager.AddFuncWithSideEffects("incr", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) var num int if ok { str, _ := elem.Value.(string) num, err := strconv.Atoi(str) if err != nil { panic(err) } num += 1 elem.Value = fmt.Sprintf("%d", num) } else { num = 1 db.StoreSet(args[0], &data.Entry{"-1", StringType}) } return reply.IntReply(num) }) store.DefaultDBManager.AddFuncWithSideEffects("incrby", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) var num int decrby, err := strconv.Atoi(args[1]) if err != nil { panic(err) } if ok { str, _ := elem.Value.(string) num, err := strconv.Atoi(str) if err != nil { panic(err) } num += decrby elem.Value = fmt.Sprintf("%d", num) } else { str := fmt.Sprintf("%d", decrby) db.StoreSet(args[0], &data.Entry{str, StringType}) } println(num) return reply.IntReply(num) }) store.DefaultDBManager.AddFunc("get", func(db *store.DB, args []string) string { elem, ok, err := db.StoreGet(args[0], StringType) if err != nil { return reply.ErrorReply(err) } if ok { str := elem.GetString() return reply.BulkReply(str) } else { return reply.NilReply } }) store.DefaultDBManager.AddFunc("getset", func(db *store.DB, args []string) string { elem, ok, err := db.StoreGet(args[0], StringType) if err != nil { return reply.ErrorReply(err) } if ok { str := elem.GetString() elem.Value = args[1] return reply.BulkReply(str) } else { db.StoreSet(args[0], &data.Entry{args[1], StringType}) return reply.NilReply } }) store.DefaultDBManager.AddFuncWithSideEffects("psetex", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) millis, err := strconv.Atoi(args[1]) if err != nil { panic(err) } db.ExpiryRecord[args[0]] = store.Milliseconds() + uint64(millis) if ok { elem.Value = args[2] } else { db.StoreSet(args[0], &data.Entry{args[2], StringType}) } return reply.OKReply }) store.DefaultDBManager.AddFuncWithSideEffects("setex", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) seconds, err := strconv.Atoi(args[1]) if err != nil { panic(err) } db.ExpiryRecord[args[0]] = store.Milliseconds() + uint64(seconds)*1000 if ok { elem.Value = args[2] } else { db.StoreSet(args[0], &data.Entry{args[2], StringType}) } return reply.OKReply }) store.DefaultDBManager.AddFuncWithSideEffects("set", func(db *store.DB, args []string) string { elem, ok, _ := db.StoreGet(args[0], StringType) if ok { elem.Value = args[1] } else { db.StoreSet(args[0], &data.Entry{args[1], StringType}) } return reply.OKReply }) store.DefaultDBManager.AddFuncWithSideEffects("setnx", func(db *store.DB, args []string) string { s := args[0] _, ok, _ := db.StoreGet(s, StringType) if ok { return reply.IntReply(0) } db.StoreSet(s, &data.Entry{args[1], StringType}) return reply.IntReply(1) }) store.DefaultDBManager.AddFunc("strlen", func(db *store.DB, args []string) string { elem, ok, err := db.StoreGet(args[0], StringType) if err != nil { return reply.ErrorReply(err) } if ok { str := elem.GetString() return reply.IntReply(len(str)) } else { return reply.IntReply(0) } }) }
func init() { gob.Register(&Post{}) gob.Register(&Feed{}) store.RegisterStoreType(FeedType) store.DefaultDBManager.AddFuncWithSideEffects("feedcap", func(db *store.DB, args []string) string { s := args[0] cap, err := strconv.Atoi(args[1]) if err != nil { return reply.ErrorReply(err) } e, ok, _ := db.StoreGet(s, FeedType) if ok { if f, ok := e.Value.(*Feed); ok { f.Capacity = cap return reply.OKReply } else { return reply.ErrorReply("Type Mismatch") } } else { f := &Feed{s, cap, 0, make([]*Post, 0)} db.StoreSet(s, &data.Entry{f, FeedType}) } return reply.OKReply }) store.DefaultDBManager.AddFunc("feedget", func(db *store.DB, args []string) string { if e, ok, _ := db.StoreGet(args[0], FeedType); ok { if f, ok := e.Value.(*Feed); ok { cap_str := fmt.Sprintf("%d", f.Capacity) var rep reply.MultiBulkWriter rep.WriteCount(2) rep.WriteString(f.Name) rep.WriteString(cap_str) return rep.String() } else { return "-ERR Type mismatch\r\n" } } else { return reply.NilReply } }) store.DefaultDBManager.AddFuncWithSideEffects("feedpost", func(db *store.DB, args []string) string { e, ok, _ := db.StoreGet(args[0], FeedType) if !ok { s := args[0] f := &Feed{s, -1, 0, make([]*Post, 0)} e = &data.Entry{f, FeedType} db.StoreSet(s, e) } if f, ok := e.Value.(*Feed); ok { timestamp := store.Milliseconds() if timestamp == f.LastTimestamp { timestamp += 1 } f.LastTimestamp = timestamp p := &Post{args[1], args[2], timestamp, 0, make(map[string]string)} f.Posts = append(f.Posts, p) return reply.OKReply } else { return reply.ErrorReply("Type mismatch") } }) store.DefaultDBManager.AddFunc("feedposts", func(db *store.DB, args []string) string { if e, ok, _ := db.StoreGet(args[0], FeedType); ok { if f, ok := e.Value.(*Feed); ok { post_count := len(f.Posts) offset := 0 count := post_count if len(args) == 3 { var err error offset, err = strconv.Atoi(args[1]) if err != nil { panic(err) } count, err = strconv.Atoi(args[2]) if err != nil { panic(err) } } if offset >= post_count { return reply.NilReply } if offset+count > post_count { count = post_count - offset } var rep reply.MultiBulkWriter rep.WriteCount(3 * post_count) for i := post_count - offset; i >= post_count-offset-count; i-- { p := f.Posts[i] timestamp_str := fmt.Sprintf("%d", p.Timestamp) rep.WriteString(p.Author) rep.WriteString(p.Body) rep.WriteString(timestamp_str) } return rep.String() } else { return reply.ErrorReply("Type mismatch") } } else { return reply.NilReply } }) store.DefaultDBManager.AddFunc("feedlen", func(db *store.DB, args []string) string { if e, ok, _ := db.StoreGet(args[0], FeedType); ok { if f, ok := e.Value.(*Feed); ok { return reply.IntReply(len(f.Posts)) } } return reply.NilReply }) //store.DefaultDBManager.AddFuncWithSideEffects("feedlike", func (db *store.DB, args []string) string { //}) }