| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- // Author: simon (ynwdlxm@163.com)
- // Date: 2025/9/16 16:56
- // Desc:
- package database
- import (
- "github.com/runningwater/go-redis/interface/resp"
- "github.com/runningwater/go-redis/lib/utils"
- "github.com/runningwater/go-redis/lib/wildcard"
- "github.com/runningwater/go-redis/resp/reply"
- )
- // 语法:
- //
- // DEL key [key ...]
- //
- // 返回:
- //
- // Integer reply: the number of keys that were removed.
- func execDel(db *DB, args [][]byte) resp.Reply {
- keys := make([]string, len(args))
- for i, v := range args {
- keys[i] = string(v)
- }
- deleted := db.Removes(keys...)
- if deleted > 0 {
- db.addAof(utils.ToCmdLine2("DEL", args...))
- }
- return reply.NewIntReply(int64(deleted))
- }
- // 语法:
- //
- // EXISTS key [key ...]
- //
- // 返回:
- //
- // Integer reply: the number of keys that exists.
- func execExists(db *DB, args [][]byte) resp.Reply {
- result := int64(0)
- for _, key := range args {
- if _, exists := db.GetEntity(string(key)); exists {
- result++
- }
- }
- return reply.NewIntReply(result)
- }
- // 语法:
- //
- // FLUSHDB [ASYNC | SYNC]
- //
- // 返回:
- //
- // Simple string reply: OK.
- func execFlushDb(db *DB, args [][]byte) resp.Reply {
- db.Flush()
- db.addAof(utils.ToCmdLine2("FLUSHDB", args...))
- return reply.NewOkReply()
- }
- // 语法:
- //
- // KEYS pattern
- //
- // Supported glob-style patterns:
- //
- // h?llo matches hello, hallo and hxllo
- // h*llo matches hllo and heeeello
- // h[ae]llo matches hello and hallo, but not hillo
- // h[^e]llo matches hallo, hbllo, ... but not hello
- // h[a-b]llo matches hallo and hbllo
- //
- // Use \ to escape special characters if you want to match them verbatim.
- //
- // 返回:
- //
- // Array reply: a list of keys matching pattern.
- func execKeys(db *DB, args [][]byte) resp.Reply {
- pattern := string(args[0])
- compilePattern := wildcard.CompilePattern(pattern)
- result := make([][]byte, 0)
- db.data.ForEach(func(key string, value any) bool {
- if compilePattern.IsMatch(key) {
- result = append(result, []byte(key))
- }
- return true
- })
- return reply.NewMultiBulkReply(result)
- }
- // 语法:
- //
- // TYPE key
- //
- // 返回:
- //
- // Returns the string representation of the type of the value stored at key.
- // The different types that can be returned are: string, list, set, zset, hash, stream, and vectorset.
- func execType(db *DB, args [][]byte) resp.Reply {
- key := string(args[0])
- entity, exists := db.GetEntity(key)
- if !exists {
- return reply.NewStatusReply("none")
- }
- switch entity.Data.(type) {
- case []byte:
- return reply.NewStatusReply("string")
- // : TODO 类型判断: 只实现了 string 类型, 其他类型未实现
- default:
- return reply.NewUnknownErrReply("don't know the type")
- }
- }
- // 语法:
- //
- // RENAME key newkey
- //
- // 返回:
- //
- // returns an error when key does not exist.
- // If newkey already exists it is overwritten,
- // when this happens RENAME executes an implicit DEL operation,
- // so if the deleted key contains a very big value it may cause
- // high latency even if RENAME itself is usually a constant-time operation.
- func execRename(db *DB, args [][]byte) resp.Reply {
- src := string(args[0])
- dest := string(args[1])
- entity, exists := db.GetEntity(src)
- if !exists {
- return reply.NewErrReply("no such key")
- }
- db.PutEntity(dest, entity)
- db.Remove(src)
- db.addAof(utils.ToCmdLine2("RENAME", args...))
- return reply.NewOkReply()
- }
- // 语法:
- //
- // RENAMENX key newkey
- //
- // 返回:
- //
- // Integer reply: 1 if key was renamed to newkey.
- // Integer reply: 0 if newkey already exists.
- func execRenamenx(db *DB, args [][]byte) resp.Reply {
- src := string(args[0])
- dest := string(args[1])
- _, ok := db.GetEntity(dest)
- if ok {
- return reply.NewIntReply(0)
- }
- entity, exists := db.GetEntity(src)
- if !exists {
- return reply.NewErrReply("no such key")
- }
- db.PutEntity(dest, entity)
- db.Remove(src)
- db.addAof(utils.ToCmdLine2("RENAMENX", args...))
- return reply.NewIntReply(1)
- }
- // init 将键相关命令注册到命令表中
- // 此函数在包初始化期间自动调用
- func init() {
- // 注册 DEL 命令,至少需要 2 个参数(命令名称 + 至少 1 个键)
- RegisterCommand("DEL", execDel, -2)
- // 注册 EXISTS 命令,至少需要 2 个参数(命令名称 + 至少 1 个键)
- RegisterCommand("EXISTS", execExists, -2)
- // 注册 FLUSHDB 命令,至少需要 1 个参数(命令名称)
- RegisterCommand("FLUSHDB", execFlushDb, -1)
- // 注册 RENAME 命令,需要 2 个参数(命令名称 + 源键 + 目标键)
- RegisterCommand("KEYS", execKeys, 2)
- // 注册 TYPE 命令,需要 2 个参数(命令名称 + 键)
- RegisterCommand("TYPE", execType, 2)
- // 注册 TYPE 命令,需要 3 个参数(命令名称 + 键)
- RegisterCommand("RENAME", execRename, 3)
- // 注册 RENAMENX 命令,需要 3 个参数(命令名称 + 源键 + 目标键)
- RegisterCommand("RENAMENX", execRenamenx, 3)
- }
|