package commands import ( "errors" "net" "redisClone/pkg/core" "redisClone/pkg/pubsub" ) var dbInstance core.RedisDB func SetDB(db core.RedisDB) { dbInstance = db } func SingleKey(args []string) []string { return []string{args[1]} } func AllSubsequentKeys(args []string) []string { return args[1:] } func NoKeys(args []string) []string { return nil } func RenameKeys(args []string) []string { return []string{args[1], args[2]} } type BaseCommand struct{ MinArgs int ExtractKeys func(args []string)[]string Execute func(args []string, getShard func(k string) *core.Shard) interface{} } func DispatchBaseCommand(db core.RedisDB ,cmd BaseCommand, args []string) interface{} { if len(args) < cmd.MinArgs { return errors.New("wrong number of arguments") } keys := cmd.ExtractKeys(args) db.Lock(keys) defer db.Unlock(keys) return cmd.Execute(args, db.GetShard) } type PubSubCommand struct{ MinArgs int Execute func(hub *pubsub.Hub, conn net.Conn, args []string) interface{} } func DispatchPubSub(conn net.Conn, h *pubsub.Hub, cmd PubSubCommand, args []string) { if len(args) < cmd.MinArgs { conn.Write(core.SerializeRESP(errors.New("ERR wrong number of arguments"))) return } if res := cmd.Execute(h, conn, args); res != nil { conn.Write(core.SerializeRESP(res)) } } var BaseRegistry = map[string]BaseCommand{ "GET": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Get, }, "SET": { MinArgs: 3, ExtractKeys: SingleKey, Execute: Set, }, "DEL": { MinArgs: 2, ExtractKeys: AllSubsequentKeys, Execute: Del, }, "EXISTS": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Exists, }, "INCR": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Incr, }, "DECR": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Decr, }, "RENAME": { MinArgs: 3, ExtractKeys: RenameKeys, Execute: Rename, }, "RPUSH": { MinArgs: 3, ExtractKeys: SingleKey, Execute: Rpush, }, "LPUSH": { MinArgs: 3, ExtractKeys: SingleKey, Execute: Lpush, }, "RPOP": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Rpop, }, "LPOP": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Lpop, }, "LRANGE": { MinArgs: 4, ExtractKeys: SingleKey, Execute: Lrange, }, "FLUSHALL": { MinArgs: 1, ExtractKeys: NoKeys, Execute: Flushall, }, "EXPIRE": { MinArgs: 3, ExtractKeys: SingleKey, Execute: Expire, }, "HSET": { MinArgs: 4, ExtractKeys: SingleKey, Execute: Hset, }, "HGET": { MinArgs: 3, ExtractKeys: SingleKey, Execute: Hget, }, "HGETALL": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Hgetall, }, "HKEYS": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Hkeys, }, "HVALUES": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Hvalues, }, "TYPE": { MinArgs: 2, ExtractKeys: SingleKey, Execute: Type, }, "DBSIZE": { MinArgs: 1, ExtractKeys: NoKeys, Execute: Dbsize, }, "KEYS": { MinArgs: 2, ExtractKeys: NoKeys, Execute: Keys, }, "LREM": { MinArgs: 4, ExtractKeys: SingleKey, Execute: Lrem, }, "PING": { MinArgs: 1, ExtractKeys: NoKeys, Execute: Ping, }, } var PubSubRegistry = map[string]PubSubCommand{ "SUBSCRIBE": {MinArgs: 2, Execute: Subscribe}, "UNSUBSCRIBE": {MinArgs: 1, Execute: Unsubscribe}, "PUBLISH": {MinArgs: 3, Execute: Publish}, }