resp_database.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Author: simon (ynwdlxm@163.com)
  2. // Date: 2025/9/25 11:27
  3. // Desc: 处理 RESP-SPEC 命令
  4. package database
  5. import (
  6. "strconv"
  7. "strings"
  8. "github.com/runningwater/go-redis/aof"
  9. "github.com/runningwater/go-redis/config"
  10. "github.com/runningwater/go-redis/interface/resp"
  11. "github.com/runningwater/go-redis/lib/logger"
  12. "github.com/runningwater/go-redis/resp/reply"
  13. )
  14. type Database struct {
  15. dbSet []*DB
  16. aofHandler *aof.Handler
  17. }
  18. func NewDatabase() *Database {
  19. if config.Properties.Databases == 0 {
  20. config.Properties.Databases = 16
  21. }
  22. database := &Database{}
  23. database.dbSet = make([]*DB, config.Properties.Databases)
  24. // 初始化数据库集合
  25. for i := range database.dbSet {
  26. db := NewDB()
  27. db.index = i
  28. database.dbSet[i] = db
  29. }
  30. if config.Properties.AppendOnly {
  31. aofHandler, err := aof.NewAofHandler(database)
  32. if err != nil {
  33. panic(err)
  34. }
  35. database.aofHandler = aofHandler
  36. }
  37. for _, db := range database.dbSet {
  38. d := db
  39. d.addAof = func(line CmdLine) {
  40. database.aofHandler.AddAof(d.index, line)
  41. }
  42. }
  43. return database
  44. }
  45. func (d *Database) Exec(client resp.Connection, args [][]byte) resp.Reply {
  46. defer func() {
  47. if err := recover(); err != nil {
  48. logger.Error(err)
  49. }
  50. }()
  51. cmdName := strings.ToLower(string(args[0]))
  52. if cmdName == "select" {
  53. if len(args) != 2 {
  54. return reply.NewErrReply("ERR wrong number of arguments for 'select' command")
  55. }
  56. return execSelect(client, d, args[1:])
  57. } else if cmdName == "command" {
  58. return reply.NewOkReply()
  59. }
  60. index := client.GetDBIndex()
  61. return d.dbSet[index].Exec(client, args)
  62. }
  63. func (d *Database) Close() {
  64. // TODO implement me
  65. }
  66. func (d *Database) AfterClientClose(client resp.Connection) {
  67. // TODO implement me
  68. }
  69. // execSelect 处理数据库选择命令
  70. //
  71. // 参数:
  72. //
  73. // c: 客户端连接对象,用于执行数据库切换操作
  74. // database: 数据库实例,包含所有可用的数据库集合
  75. // args: 命令参数,第一个参数为要选择的数据库索引
  76. //
  77. // 返回值:
  78. //
  79. // resp.Reply: 执行结果回复,成功返回OK,失败返回错误信息
  80. func execSelect(c resp.Connection, database *Database, args [][]byte) resp.Reply {
  81. // 解析数据库索引参数
  82. dbIndex, err := strconv.Atoi(string(args[0]))
  83. if err != nil {
  84. return reply.NewErrReply("ERR invalid DB index")
  85. }
  86. // 验证数据库索引范围
  87. if dbIndex >= len(database.dbSet) {
  88. return reply.NewErrReply("ERR DB index is out of range")
  89. }
  90. // 执行数据库切换操作
  91. c.SelectDB(dbIndex)
  92. return reply.NewOkReply()
  93. }