|
|
@@ -0,0 +1,88 @@
|
|
|
+// Author: simon (ynwdlxm@163.com)
|
|
|
+// Date: 2025/9/15 18:04
|
|
|
+// Desc:
|
|
|
+
|
|
|
+package database
|
|
|
+
|
|
|
+import (
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/runningwater/go-redis/datastruct/dict"
|
|
|
+ "github.com/runningwater/go-redis/interface/database"
|
|
|
+ "github.com/runningwater/go-redis/interface/resp"
|
|
|
+ "github.com/runningwater/go-redis/resp/reply"
|
|
|
+)
|
|
|
+
|
|
|
+type DB struct {
|
|
|
+ index int
|
|
|
+ data dict.Dict
|
|
|
+}
|
|
|
+
|
|
|
+type ExecFunc func(db *DB, args [][]byte) resp.Reply
|
|
|
+type CmdLine = [][]byte
|
|
|
+
|
|
|
+func NewDB() *DB {
|
|
|
+ return &DB{
|
|
|
+ index: 0,
|
|
|
+ data: dict.NewSyncDict(),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) Exec(c resp.Connection, cmdLine CmdLine) resp.Reply {
|
|
|
+ // ping set setnx get
|
|
|
+ cmdName := strings.ToLower(string(cmdLine[0]))
|
|
|
+ // 查表
|
|
|
+ cmd, ok := cmdTable[cmdName]
|
|
|
+ if !ok {
|
|
|
+ return reply.NewUnknownErrReply(cmdName)
|
|
|
+ }
|
|
|
+ // 参数校验
|
|
|
+ if !validateArity(cmd.arity, cmdLine[1:]) {
|
|
|
+ return reply.NewArgNumErrReply(cmdName)
|
|
|
+ }
|
|
|
+
|
|
|
+ if cmd.executor == nil {
|
|
|
+ return reply.NewErrReply("command not implement")
|
|
|
+ }
|
|
|
+ return cmd.executor(d, cmdLine[1:])
|
|
|
+}
|
|
|
+
|
|
|
+func validateArity(arity int, args [][]byte) bool {
|
|
|
+ if arity >= 0 {
|
|
|
+ return arity == len(args)
|
|
|
+ }
|
|
|
+ // 变长的 arity 设置为 负的最小个数
|
|
|
+ return len(args) >= -arity
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) GetEntity(key string) (*database.DataEntity, bool) {
|
|
|
+ raw, ok := d.data.Get(key)
|
|
|
+ if !ok {
|
|
|
+ return nil, false
|
|
|
+ }
|
|
|
+ entity, _ := raw.(*database.DataEntity)
|
|
|
+ return entity, true
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) PutEntity(key string, entity *database.DataEntity) int {
|
|
|
+ return d.data.Put(key, entity)
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) Remove(key string) {
|
|
|
+ d.data.Remove(key)
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) Removes(keys ...string) (deleted int) {
|
|
|
+ deleted = 0
|
|
|
+ for _, key := range keys {
|
|
|
+ if _, exists := d.data.Get(key); exists {
|
|
|
+ d.Remove(key)
|
|
|
+ deleted++
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DB) Flush() {
|
|
|
+ d.data.Clear()
|
|
|
+}
|