cmd_string.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Author: simon (ynwdlxm@163.com)
  2. // Date: 2025/9/18 15:47
  3. // Desc: GET SET SETNX GETSET STRLEN
  4. package database
  5. import (
  6. "github.com/runningwater/go-redis/interface/database"
  7. "github.com/runningwater/go-redis/interface/resp"
  8. "github.com/runningwater/go-redis/lib/utils"
  9. "github.com/runningwater/go-redis/resp/reply"
  10. )
  11. // 语法:
  12. //
  13. // GET key
  14. //
  15. // 返回:
  16. // 1. key不存在时,返回nil
  17. // 2. key存在时,返回value
  18. func execGet(db *DB, args [][]byte) resp.Reply {
  19. key := string(args[0])
  20. entity, exists := db.GetEntity(key)
  21. if !exists {
  22. return reply.NewNullBulkReply()
  23. }
  24. // 获取 value, 转换为 []byte
  25. bytes := entity.Data.([]byte)
  26. return reply.NewBulkReply(bytes)
  27. }
  28. // 语法:
  29. //
  30. // SET key value [NX] [XX] [EX seconds] [PX milliseconds] [KEEPTTL]
  31. //
  32. // 命令返回:
  33. // 1. 设置成功时,返回 OK
  34. // 2. 设置失败时,返回 NIL
  35. //
  36. // 命令参数:
  37. // 1. NX:如果 key 已经存在,则返回 NIL
  38. // 2. XX:如果 key 不存在,则返回 NIL
  39. // 3. EX seconds:设置 key 的过期时间,单位为秒
  40. // 4. PX milliseconds:设置 key 的过期时间,单位为毫秒
  41. func execSet(db *DB, args [][]byte) resp.Reply {
  42. // : TODO 暂只实现了 set key value
  43. key := string(args[0])
  44. value := args[1]
  45. entity := &database.DataEntity{
  46. Data: value,
  47. }
  48. _ = db.PutEntity(key, entity)
  49. db.addAof(utils.ToCmdLine2("SET", args...))
  50. return reply.NewOkReply()
  51. }
  52. // 语法:
  53. //
  54. // SETNX key value
  55. //
  56. // 命令返回:
  57. // 1. 设置成功时,返回 1
  58. // 2. 设置失败时,返回 0
  59. func execSetNX(db *DB, args [][]byte) resp.Reply {
  60. key := string(args[0])
  61. value := args[1]
  62. entity := &database.DataEntity{
  63. Data: value,
  64. }
  65. absent := db.PutIfAbsent(key, entity)
  66. db.addAof(utils.ToCmdLine2("SETNX", args...))
  67. return reply.NewIntReply(int64(absent))
  68. }
  69. // 语法:
  70. //
  71. // GETSET key value
  72. //
  73. // 命令返回:
  74. // 1. 获取成功时,返回旧值
  75. // 2. 获取失败时,返回 NIL
  76. func execGetSet(db *DB, args [][]byte) resp.Reply {
  77. key := string(args[0])
  78. value := args[1]
  79. entity, exists := db.GetEntity(key)
  80. _ = db.PutEntity(key, &database.DataEntity{Data: value})
  81. db.addAof(utils.ToCmdLine2("GETSET", args...))
  82. if !exists {
  83. return reply.NewNullBulkReply()
  84. }
  85. // 获取旧值
  86. bytes := entity.Data.([]byte)
  87. return reply.NewBulkReply(bytes)
  88. }
  89. // 语法:
  90. //
  91. // STRLEN key
  92. //
  93. // 命令返回:
  94. // 1. 获取成功时,返回字符串的长度
  95. // 2. 获取失败时,返回 0
  96. func execStrLen(db *DB, args [][]byte) resp.Reply {
  97. key := string(args[0])
  98. entity, exists := db.GetEntity(key)
  99. if !exists {
  100. return reply.NewIntReply(0)
  101. }
  102. // 获取字符串长度
  103. bytes := entity.Data.([]byte)
  104. return reply.NewIntReply(int64(len(bytes)))
  105. }
  106. // init 将键相关命令注册到命令表中
  107. // 此函数在包初始化期间自动调用
  108. func init() {
  109. // 注册 GET 命令,需要 2 个参数(命令名称 + 键)
  110. RegisterCommand("get", execGet, 2)
  111. // 注册 SET 命令,需要 3 个参数(命令名称 + 键 + 值)
  112. RegisterCommand("set", execSet, 3)
  113. // 注册 SETNX 命令,需要 3 个参数(命令名称 + 键 + 值)
  114. RegisterCommand("setnx", execSetNX, 3)
  115. // 注册 GETSET 命令,需要 3 个参数(命令名称 + 键 + 值)
  116. RegisterCommand("getset", execGetSet, 3)
  117. // 注册 STRLEN 命令,需要 2 个参数(命令名称 + 键)
  118. RegisterCommand("strlen", execStrLen, 2)
  119. }