package kvdb import ( "github.com/go-redis/redis" "strings" ) type ( RedisDb struct { addr string db int password string engine *redis.Client } redisIterator struct { pos int //当前位置 cursor uint64 //游标位置 key string //当前获取的key keys []string //存储的keys数组 prefix string //搜索的前缀 flag int32 //是否结束搜索 client *redis.Client } ) func (i *redisIterator) Next() bool { if (i.keys == nil || i.pos >= len(i.keys)) && i.flag != 1 { ret := i.client.Scan(i.cursor, i.prefix, 100) if ret.Err() != nil { return false } i.keys, i.cursor = ret.Val() if i.cursor == 0 { i.flag = 1 } i.pos = 0 } if i.pos < len(i.keys) { i.key = i.keys[i.pos] i.pos++ return true } return false } func (i *redisIterator) Key() string { return strings.TrimPrefix(i.key,"kv:db$:") } func (i *redisIterator) Value() []byte { cmd := i.client.Get(i.key) if cmd.Err() == nil { return []byte(cmd.Val()) } else { return nil } } func (i *redisIterator) Close() error { i.pos = 0 return nil } func newRedisIterator(c *redis.Client, prefix string) *redisIterator { if !strings.HasSuffix(prefix, "*") { prefix = prefix + "*" } return &redisIterator{client: c, prefix: prefix} } func (db *RedisDb) Open() error { db.engine = redis.NewClient(&redis.Options{ Addr: db.addr, Password: db.password, DB: db.db, }) return db.engine.Ping().Err() } func (db *RedisDb) generateKey(s string) string { return "kv:db$:" + s } func (db *RedisDb) Put(s string, bytes []byte) error { return db.engine.Set(db.generateKey(s), string(bytes), 0).Err() } func (db *RedisDb) Get(s string) ([]byte, error) { cmd := db.engine.Get(db.generateKey(s)) if cmd.Err() == nil { return []byte(cmd.Val()), nil } else { return nil, cmd.Err() } } func (db *RedisDb) Delete(s string) error { return db.engine.Del(db.generateKey(s)).Err() } func (db *RedisDb) Iterator(s string) (Iterator, error) { return newRedisIterator(db.engine, db.generateKey(s)), nil } func (db *RedisDb) Close() error { return db.engine.Close() } func NewRedis(addr, password string, db int) *RedisDb { return &RedisDb{ addr: addr, password: password, db: db, } }