string.go 3.1 KB

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