// Author: simon (ynwdlxm@163.com) // Date: 2025/9/18 15:47 // Desc: GET SET SETNX GETSET STRLEN package database import ( "github.com/runningwater/go-redis/interface/database" "github.com/runningwater/go-redis/interface/resp" "github.com/runningwater/go-redis/lib/utils" "github.com/runningwater/go-redis/resp/reply" ) // 语法: // // GET key // // 返回: // 1. key不存在时,返回nil // 2. key存在时,返回value func execGet(db *DB, args [][]byte) resp.Reply { key := string(args[0]) entity, exists := db.GetEntity(key) if !exists { return reply.NewNullBulkReply() } // 获取 value, 转换为 []byte bytes := entity.Data.([]byte) return reply.NewBulkReply(bytes) } // 语法: // // SET key value [NX] [XX] [EX seconds] [PX milliseconds] [KEEPTTL] // // 命令返回: // 1. 设置成功时,返回 OK // 2. 设置失败时,返回 NIL // // 命令参数: // 1. NX:如果 key 已经存在,则返回 NIL // 2. XX:如果 key 不存在,则返回 NIL // 3. EX seconds:设置 key 的过期时间,单位为秒 // 4. PX milliseconds:设置 key 的过期时间,单位为毫秒 func execSet(db *DB, args [][]byte) resp.Reply { // : TODO 暂只实现了 set key value key := string(args[0]) value := args[1] entity := &database.DataEntity{ Data: value, } _ = db.PutEntity(key, entity) db.addAof(utils.ToCmdLine2("SET", args...)) return reply.NewOkReply() } // 语法: // // SETNX key value // // 命令返回: // 1. 设置成功时,返回 1 // 2. 设置失败时,返回 0 func execSetNX(db *DB, args [][]byte) resp.Reply { key := string(args[0]) value := args[1] entity := &database.DataEntity{ Data: value, } absent := db.PutIfAbsent(key, entity) db.addAof(utils.ToCmdLine2("SETNX", args...)) return reply.NewIntReply(int64(absent)) } // 语法: // // GETSET key value // // 命令返回: // 1. 获取成功时,返回旧值 // 2. 获取失败时,返回 NIL func execGetSet(db *DB, args [][]byte) resp.Reply { key := string(args[0]) value := args[1] entity, exists := db.GetEntity(key) _ = db.PutEntity(key, &database.DataEntity{Data: value}) db.addAof(utils.ToCmdLine2("GETSET", args...)) if !exists { return reply.NewNullBulkReply() } // 获取旧值 bytes := entity.Data.([]byte) return reply.NewBulkReply(bytes) } // 语法: // // STRLEN key // // 命令返回: // 1. 获取成功时,返回字符串的长度 // 2. 获取失败时,返回 0 func execStrLen(db *DB, args [][]byte) resp.Reply { key := string(args[0]) entity, exists := db.GetEntity(key) if !exists { return reply.NewIntReply(0) } // 获取字符串长度 bytes := entity.Data.([]byte) return reply.NewIntReply(int64(len(bytes))) } // init 将键相关命令注册到命令表中 // 此函数在包初始化期间自动调用 func init() { // 注册 GET 命令,需要 2 个参数(命令名称 + 键) RegisterCommand("get", execGet, 2) // 注册 SET 命令,需要 3 个参数(命令名称 + 键 + 值) RegisterCommand("set", execSet, 3) // 注册 SETNX 命令,需要 3 个参数(命令名称 + 键 + 值) RegisterCommand("setnx", execSetNX, 3) // 注册 GETSET 命令,需要 3 个参数(命令名称 + 键 + 值) RegisterCommand("getset", execGetSet, 3) // 注册 STRLEN 命令,需要 2 个参数(命令名称 + 键) RegisterCommand("strlen", execStrLen, 2) }