mirror of https://github.com/ledisdb/ledisdb.git
Merge branch 'develop'
This commit is contained in:
commit
da87fe0d5f
|
@ -12,7 +12,7 @@ LedisDB now supports multiple databases as backend to store data, you can test a
|
||||||
+ Supports transaction using LMDB or BotlDB.
|
+ Supports transaction using LMDB or BotlDB.
|
||||||
+ Supports lua scripting.
|
+ Supports lua scripting.
|
||||||
+ Supports expiration and ttl.
|
+ Supports expiration and ttl.
|
||||||
+ Redis clients, like redis-cli, are supported directly.
|
+ Supports using redis-cli directly.
|
||||||
+ Multiple client API supports, including Go, Python, Lua(Openresty), C/C++, Node.js.
|
+ Multiple client API supports, including Go, Python, Lua(Openresty), C/C++, Node.js.
|
||||||
+ Easy to embed in your own Go application.
|
+ Easy to embed in your own Go application.
|
||||||
+ Restful API support, json/bson/msgpack output.
|
+ Restful API support, json/bson/msgpack output.
|
||||||
|
|
|
@ -384,14 +384,14 @@ class Ledis(object):
|
||||||
"Removes an expiration on name"
|
"Removes an expiration on name"
|
||||||
return self.execute_command('PERSIST', name)
|
return self.execute_command('PERSIST', name)
|
||||||
|
|
||||||
def scan(self, key="" , match=None, count=10):
|
def xscan(self, key="" , match=None, count=10):
|
||||||
pieces = [key]
|
pieces = [key]
|
||||||
if match is not None:
|
if match is not None:
|
||||||
pieces.extend(["MATCH", match])
|
pieces.extend(["MATCH", match])
|
||||||
|
|
||||||
pieces.extend(["COUNT", count])
|
pieces.extend(["COUNT", count])
|
||||||
|
|
||||||
return self.execute_command("SCAN", *pieces)
|
return self.execute_command("XSCAN", *pieces)
|
||||||
|
|
||||||
def scan_iter(self, match=None, count=10):
|
def scan_iter(self, match=None, count=10):
|
||||||
key = ""
|
key = ""
|
||||||
|
@ -475,8 +475,8 @@ class Ledis(object):
|
||||||
"Removes an expiration on ``name``"
|
"Removes an expiration on ``name``"
|
||||||
return self.execute_command('LPERSIST', name)
|
return self.execute_command('LPERSIST', name)
|
||||||
|
|
||||||
def lscan(self, key="", match=None, count=10):
|
def lxscan(self, key="", match=None, count=10):
|
||||||
return self.scan_generic("LSCAN", key=key, match=match, count=count)
|
return self.scan_generic("LXSCAN", key=key, match=match, count=count)
|
||||||
|
|
||||||
|
|
||||||
#### SET COMMANDS ####
|
#### SET COMMANDS ####
|
||||||
|
@ -575,8 +575,8 @@ class Ledis(object):
|
||||||
"Removes an expiration on name"
|
"Removes an expiration on name"
|
||||||
return self.execute_command('SPERSIST', name)
|
return self.execute_command('SPERSIST', name)
|
||||||
|
|
||||||
def sscan(self, key="", match=None, count = 10):
|
def sxscan(self, key="", match=None, count = 10):
|
||||||
return self.scan_generic("SSCAN", key=key, match=match, count=count)
|
return self.scan_generic("SXSCAN", key=key, match=match, count=count)
|
||||||
|
|
||||||
|
|
||||||
#### SORTED SET COMMANDS ####
|
#### SORTED SET COMMANDS ####
|
||||||
|
@ -783,8 +783,8 @@ class Ledis(object):
|
||||||
scan_type = scan_type.upper()
|
scan_type = scan_type.upper()
|
||||||
return self.execute_command(scan_type, *pieces)
|
return self.execute_command(scan_type, *pieces)
|
||||||
|
|
||||||
def zscan(self, key="", match=None, count=10):
|
def zxscan(self, key="", match=None, count=10):
|
||||||
return self.scan_generic("ZSCAN", key=key, match=match, count=count)
|
return self.scan_generic("ZXSCAN", key=key, match=match, count=count)
|
||||||
|
|
||||||
#### HASH COMMANDS ####
|
#### HASH COMMANDS ####
|
||||||
def hdel(self, name, *keys):
|
def hdel(self, name, *keys):
|
||||||
|
@ -878,8 +878,8 @@ class Ledis(object):
|
||||||
"Removes an expiration on name"
|
"Removes an expiration on name"
|
||||||
return self.execute_command('HPERSIST', name)
|
return self.execute_command('HPERSIST', name)
|
||||||
|
|
||||||
def hscan(self, key="", match=None, count=10):
|
def hxscan(self, key="", match=None, count=10):
|
||||||
return self.scan_generic("HSCAN", key=key, match=match, count=count)
|
return self.scan_generic("HXSCAN", key=key, match=match, count=count)
|
||||||
|
|
||||||
|
|
||||||
### BIT COMMANDS
|
### BIT COMMANDS
|
||||||
|
@ -957,8 +957,8 @@ class Ledis(object):
|
||||||
"Removes an expiration on name"
|
"Removes an expiration on name"
|
||||||
return self.execute_command('BPERSIST', name)
|
return self.execute_command('BPERSIST', name)
|
||||||
|
|
||||||
def bscan(self, key="", match=None, count=10):
|
def bxscan(self, key="", match=None, count=10):
|
||||||
return self.scan_generic("BSCAN", key=key, match=match, count=count)
|
return self.scan_generic("BXSCAN", key=key, match=match, count=count)
|
||||||
|
|
||||||
def eval(self, script, keys, *args):
|
def eval(self, script, keys, *args):
|
||||||
n = len(keys)
|
n = len(keys)
|
||||||
|
|
|
@ -63,12 +63,12 @@ class TestOtherCommands(unittest.TestCase):
|
||||||
|
|
||||||
def check_keys(self, scan_type):
|
def check_keys(self, scan_type):
|
||||||
d = {
|
d = {
|
||||||
"scan": l.scan,
|
"xscan": l.xscan,
|
||||||
"sscan": l.sscan,
|
"sxscan": l.sxscan,
|
||||||
"lscan": l.lscan,
|
"lxscan": l.lxscan,
|
||||||
"hscan": l.hscan,
|
"hxscan": l.hxscan,
|
||||||
"zscan": l.zscan,
|
"zxscan": l.zxscan,
|
||||||
"bscan": l.bscan
|
"bxscan": l.bxscan
|
||||||
}
|
}
|
||||||
|
|
||||||
key, keys = d[scan_type]()
|
key, keys = d[scan_type]()
|
||||||
|
@ -82,40 +82,40 @@ class TestOtherCommands(unittest.TestCase):
|
||||||
assert set(keys) == set([b("b"), b("c")])
|
assert set(keys) == set([b("b"), b("c")])
|
||||||
|
|
||||||
|
|
||||||
def test_scan(self):
|
def test_xscan(self):
|
||||||
d = {"a":1, "b":2, "c": 3}
|
d = {"a":1, "b":2, "c": 3}
|
||||||
l.mset(d)
|
l.mset(d)
|
||||||
self.check_keys("scan")
|
self.check_keys("xscan")
|
||||||
|
|
||||||
|
|
||||||
def test_lscan(self):
|
def test_lxscan(self):
|
||||||
l.rpush("a", 1)
|
l.rpush("a", 1)
|
||||||
l.rpush("b", 1)
|
l.rpush("b", 1)
|
||||||
l.rpush("c", 1)
|
l.rpush("c", 1)
|
||||||
self.check_keys("lscan")
|
self.check_keys("lxscan")
|
||||||
|
|
||||||
|
|
||||||
def test_hscan(self):
|
def test_hxscan(self):
|
||||||
l.hset("a", "hello", "world")
|
l.hset("a", "hello", "world")
|
||||||
l.hset("b", "hello", "world")
|
l.hset("b", "hello", "world")
|
||||||
l.hset("c", "hello", "world")
|
l.hset("c", "hello", "world")
|
||||||
self.check_keys("hscan")
|
self.check_keys("hxscan")
|
||||||
|
|
||||||
def test_sscan(self):
|
def test_sxscan(self):
|
||||||
l.sadd("a", 1)
|
l.sadd("a", 1)
|
||||||
l.sadd("b", 2)
|
l.sadd("b", 2)
|
||||||
l.sadd("c", 3)
|
l.sadd("c", 3)
|
||||||
self.check_keys("sscan")
|
self.check_keys("sxscan")
|
||||||
|
|
||||||
def test_zscan(self):
|
def test_zxscan(self):
|
||||||
l.zadd("a", 1, "a")
|
l.zadd("a", 1, "a")
|
||||||
l.zadd("b", 1, "a")
|
l.zadd("b", 1, "a")
|
||||||
l.zadd("c", 1, "a")
|
l.zadd("c", 1, "a")
|
||||||
self.check_keys("zscan")
|
self.check_keys("zxscan")
|
||||||
|
|
||||||
def test_bscan(self):
|
def test_bxscan(self):
|
||||||
l.bsetbit("a", 1, 1)
|
l.bsetbit("a", 1, 1)
|
||||||
l.bsetbit("b", 1, 1)
|
l.bsetbit("b", 1, 1)
|
||||||
l.bsetbit("c", 1, 1)
|
l.bsetbit("c", 1, 1)
|
||||||
self.check_keys("bscan")
|
self.check_keys("bxscan")
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = [
|
||||||
"bexpireat",
|
"bexpireat",
|
||||||
"bttl",
|
"bttl",
|
||||||
"bpersist",
|
"bpersist",
|
||||||
"bscan",
|
"bxscan",
|
||||||
|
|
||||||
"hdel",
|
"hdel",
|
||||||
"hexists",
|
"hexists",
|
||||||
|
@ -40,7 +40,7 @@ module.exports = [
|
||||||
"hexpireat",
|
"hexpireat",
|
||||||
"httl",
|
"httl",
|
||||||
"hpersist",
|
"hpersist",
|
||||||
"hscan",
|
"hxscan",
|
||||||
|
|
||||||
"decr",
|
"decr",
|
||||||
"decrby",
|
"decrby",
|
||||||
|
@ -58,7 +58,7 @@ module.exports = [
|
||||||
"expireat",
|
"expireat",
|
||||||
"ttl",
|
"ttl",
|
||||||
"persist",
|
"persist",
|
||||||
"scan",
|
"xscan",
|
||||||
|
|
||||||
"lindex",
|
"lindex",
|
||||||
"llen",
|
"llen",
|
||||||
|
@ -75,7 +75,7 @@ module.exports = [
|
||||||
"lexpireat",
|
"lexpireat",
|
||||||
"lttl",
|
"lttl",
|
||||||
"lpersist",
|
"lpersist",
|
||||||
"lscan",
|
"lxscan",
|
||||||
|
|
||||||
"zadd",
|
"zadd",
|
||||||
"zcard",
|
"zcard",
|
||||||
|
@ -101,7 +101,7 @@ module.exports = [
|
||||||
"zexpireat",
|
"zexpireat",
|
||||||
"zttl",
|
"zttl",
|
||||||
"zpersist",
|
"zpersist",
|
||||||
"zscan",
|
"zxscan",
|
||||||
|
|
||||||
|
|
||||||
"sadd",
|
"sadd",
|
||||||
|
@ -123,7 +123,7 @@ module.exports = [
|
||||||
"sexpireat",
|
"sexpireat",
|
||||||
"sttl",
|
"sttl",
|
||||||
"spersist",
|
"spersist",
|
||||||
"sscan",
|
"sxscan",
|
||||||
|
|
||||||
"begin",
|
"begin",
|
||||||
"rollback",
|
"rollback",
|
||||||
|
|
|
@ -40,7 +40,7 @@ local commands = {
|
||||||
"expire",
|
"expire",
|
||||||
"expireat",
|
"expireat",
|
||||||
"persist",
|
"persist",
|
||||||
"scan",
|
"xscan",
|
||||||
|
|
||||||
--[[hash]]
|
--[[hash]]
|
||||||
"hdel",
|
"hdel",
|
||||||
|
@ -61,7 +61,7 @@ local commands = {
|
||||||
"hexpireat",
|
"hexpireat",
|
||||||
"httl",
|
"httl",
|
||||||
"hpersist",
|
"hpersist",
|
||||||
"hscan",
|
"hxscan",
|
||||||
|
|
||||||
--[[list]]
|
--[[list]]
|
||||||
"lindex",
|
"lindex",
|
||||||
|
@ -78,7 +78,7 @@ local commands = {
|
||||||
"lexpireat",
|
"lexpireat",
|
||||||
"lttl",
|
"lttl",
|
||||||
"lpersist",
|
"lpersist",
|
||||||
"lscan",
|
"lxscan",
|
||||||
|
|
||||||
--[[zset]]
|
--[[zset]]
|
||||||
"zadd",
|
"zadd",
|
||||||
|
@ -102,7 +102,7 @@ local commands = {
|
||||||
"zexpireat",
|
"zexpireat",
|
||||||
"zttl",
|
"zttl",
|
||||||
"zpersist",
|
"zpersist",
|
||||||
"zscan",
|
"zxscan",
|
||||||
|
|
||||||
--[[bit]]
|
--[[bit]]
|
||||||
"bget",
|
"bget",
|
||||||
|
@ -116,7 +116,7 @@ local commands = {
|
||||||
"bexpireat",
|
"bexpireat",
|
||||||
"bttl",
|
"bttl",
|
||||||
"bpersist",
|
"bpersist",
|
||||||
"bscan",
|
"bxscan",
|
||||||
|
|
||||||
--[[set]]
|
--[[set]]
|
||||||
"sadd",
|
"sadd",
|
||||||
|
@ -138,7 +138,7 @@ local commands = {
|
||||||
"sexpireat",
|
"sexpireat",
|
||||||
"sttl",
|
"sttl",
|
||||||
"spersist",
|
"spersist",
|
||||||
"sscan",
|
"sxscan",
|
||||||
|
|
||||||
--[[server]]
|
--[[server]]
|
||||||
"ping",
|
"ping",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//This file was generated by .tools/generate_commands.py on Tue Sep 02 2014 22:27:45 +0800
|
//This file was generated by .tools/generate_commands.py on Tue Sep 09 2014 09:48:57 +0800
|
||||||
package main
|
package main
|
||||||
|
|
||||||
var helpCommands = [][]string{
|
var helpCommands = [][]string{
|
||||||
|
@ -12,9 +12,9 @@ var helpCommands = [][]string{
|
||||||
{"BMSETBIT", "key offset value [offset value ...]", "Bitmap"},
|
{"BMSETBIT", "key offset value [offset value ...]", "Bitmap"},
|
||||||
{"BOPT", "operation destkey key [key ...]", "Bitmap"},
|
{"BOPT", "operation destkey key [key ...]", "Bitmap"},
|
||||||
{"BPERSIST", "key", "Bitmap"},
|
{"BPERSIST", "key", "Bitmap"},
|
||||||
{"BSCAN", "key [MATCH match] [COUNT count]", "Bitmap"},
|
|
||||||
{"BSETBIT", "key offset value", "Bitmap"},
|
{"BSETBIT", "key offset value", "Bitmap"},
|
||||||
{"BTTL", "key", "Bitmap"},
|
{"BTTL", "key", "Bitmap"},
|
||||||
|
{"BXSCAN", "key [MATCH match] [COUNT count]", "Bitmap"},
|
||||||
{"COMMIT", "-", "Transaction"},
|
{"COMMIT", "-", "Transaction"},
|
||||||
{"DECR", "key", "KV"},
|
{"DECR", "key", "KV"},
|
||||||
{"DECRBY", "key decrement", "KV"},
|
{"DECRBY", "key decrement", "KV"},
|
||||||
|
@ -44,10 +44,10 @@ var helpCommands = [][]string{
|
||||||
{"HMGET", "key field [field ...]", "Hash"},
|
{"HMGET", "key field [field ...]", "Hash"},
|
||||||
{"HMSET", "key field value [field value ...]", "Hash"},
|
{"HMSET", "key field value [field value ...]", "Hash"},
|
||||||
{"HPERSIST", "key", "Hash"},
|
{"HPERSIST", "key", "Hash"},
|
||||||
{"HSCAN", "key [MATCH match] [COUNT count]", "Hash"},
|
|
||||||
{"HSET", "key field value", "Hash"},
|
{"HSET", "key field value", "Hash"},
|
||||||
{"HTTL", "key", "Hash"},
|
{"HTTL", "key", "Hash"},
|
||||||
{"HVALS", "key", "Hash"},
|
{"HVALS", "key", "Hash"},
|
||||||
|
{"HXSCAN", "key [MATCH match] [COUNT count]", "Hash"},
|
||||||
{"INCR", "key", "KV"},
|
{"INCR", "key", "KV"},
|
||||||
{"INCRBY", "key increment", "KV"},
|
{"INCRBY", "key increment", "KV"},
|
||||||
{"INFO", "[section]", "Server"},
|
{"INFO", "[section]", "Server"},
|
||||||
|
@ -61,8 +61,8 @@ var helpCommands = [][]string{
|
||||||
{"LPOP", "key", "List"},
|
{"LPOP", "key", "List"},
|
||||||
{"LPUSH", "key value [value ...]", "List"},
|
{"LPUSH", "key value [value ...]", "List"},
|
||||||
{"LRANGE", "key start stop", "List"},
|
{"LRANGE", "key start stop", "List"},
|
||||||
{"LSCAN", "key [MATCH match] [COUNT count]", "List"},
|
|
||||||
{"LTTL", "key", "List"},
|
{"LTTL", "key", "List"},
|
||||||
|
{"LXSCAN", "key [MATCH match] [COUNT count]", "List"},
|
||||||
{"MGET", "key [key ...]", "KV"},
|
{"MGET", "key [key ...]", "KV"},
|
||||||
{"MSET", "key value [key value ...]", "KV"},
|
{"MSET", "key value [key value ...]", "KV"},
|
||||||
{"PERSIST", "key", "KV"},
|
{"PERSIST", "key", "KV"},
|
||||||
|
@ -71,7 +71,6 @@ var helpCommands = [][]string{
|
||||||
{"RPOP", "key", "List"},
|
{"RPOP", "key", "List"},
|
||||||
{"RPUSH", "key value [value ...]", "List"},
|
{"RPUSH", "key value [value ...]", "List"},
|
||||||
{"SADD", "key member [member ...]", "Set"},
|
{"SADD", "key member [member ...]", "Set"},
|
||||||
{"SCAN", "key [MATCH match] [COUNT count]", "KV"},
|
|
||||||
{"SCARD", "key", "Set"},
|
{"SCARD", "key", "Set"},
|
||||||
{"SCLEAR", "key", "Set"},
|
{"SCLEAR", "key", "Set"},
|
||||||
{"SCRIPT EXISTS", "script [script ...]", "Script"},
|
{"SCRIPT EXISTS", "script [script ...]", "Script"},
|
||||||
|
@ -92,12 +91,13 @@ var helpCommands = [][]string{
|
||||||
{"SMEMBERS", "key", "Set"},
|
{"SMEMBERS", "key", "Set"},
|
||||||
{"SPERSIST", "key", "Set"},
|
{"SPERSIST", "key", "Set"},
|
||||||
{"SREM", "key member [member ...]", "Set"},
|
{"SREM", "key member [member ...]", "Set"},
|
||||||
{"SSCAN", "key [MATCH match] [COUNT count]", "Set"},
|
|
||||||
{"STTL", "key", "Set"},
|
{"STTL", "key", "Set"},
|
||||||
{"SUNION", "key [key ...]", "Set"},
|
{"SUNION", "key [key ...]", "Set"},
|
||||||
{"SUNIONSTORE", "destination key [key ...]", "Set"},
|
{"SUNIONSTORE", "destination key [key ...]", "Set"},
|
||||||
|
{"SXSCAN", "key [MATCH match] [COUNT count]", "Set"},
|
||||||
{"SYNC", "index offset", "Replication"},
|
{"SYNC", "index offset", "Replication"},
|
||||||
{"TTL", "key", "KV"},
|
{"TTL", "key", "KV"},
|
||||||
|
{"XSCAN", "key [MATCH match] [COUNT count]", "KV"},
|
||||||
{"ZADD", "key score member [score member ...]", "ZSet"},
|
{"ZADD", "key score member [score member ...]", "ZSet"},
|
||||||
{"ZCARD", "key", "ZSet"},
|
{"ZCARD", "key", "ZSet"},
|
||||||
{"ZCLEAR", "key", "ZSet"},
|
{"ZCLEAR", "key", "ZSet"},
|
||||||
|
@ -117,8 +117,8 @@ var helpCommands = [][]string{
|
||||||
{"ZREVRANGE", "key start stop [WITHSCORES]", "ZSet"},
|
{"ZREVRANGE", "key start stop [WITHSCORES]", "ZSet"},
|
||||||
{"ZREVRANGEBYSCORE", "key max min [WITHSCORES][LIMIT offset count]", "ZSet"},
|
{"ZREVRANGEBYSCORE", "key max min [WITHSCORES][LIMIT offset count]", "ZSet"},
|
||||||
{"ZREVRANK", "key member", "ZSet"},
|
{"ZREVRANK", "key member", "ZSet"},
|
||||||
{"ZSCAN", "key [MATCH match] [COUNT count]", "ZSet"},
|
|
||||||
{"ZSCORE", "key member", "ZSet"},
|
{"ZSCORE", "key member", "ZSet"},
|
||||||
{"ZTTL", "key", "ZSet"},
|
{"ZTTL", "key", "ZSet"},
|
||||||
{"ZUNIONSTORE", "destkey numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]", "ZSet"},
|
{"ZUNIONSTORE", "destkey numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]", "ZSet"},
|
||||||
|
{"ZXSCAN", "key [MATCH match] [COUNT count]", "ZSet"},
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
LedisDB is not Redis, so you can not use some Redis clients for LedisDB directly.
|
||||||
|
But LedisDB uses Redis protocol for communication and many APIs are same as Redis,
|
||||||
|
so you can easily write your own LedisDB client based on a Redis one.
|
||||||
|
|
||||||
|
Before you write a client, you must know some differences between LedisDB and Redis.
|
||||||
|
|
||||||
|
## Data Structure
|
||||||
|
|
||||||
|
LedisDB has no Strings data type but KV and Bitmap, any some Keys and Strings commands in Redis will only affect KV data, and "bit" commands affect Bitmap.
|
||||||
|
|
||||||
|
## Del
|
||||||
|
|
||||||
|
In Redis, `del` can delete all type data, like String, Hash, List, etc, but in LedisDB, `del` can only delete KV data. To delete other type data, you will use "clear" commands.
|
||||||
|
|
||||||
|
+ KV: `del`, `mdel`
|
||||||
|
+ Hash: `hclear`, `mhclear`
|
||||||
|
+ List: `lclear`, `mlclear`
|
||||||
|
+ Set: `sclear`, `msclear`
|
||||||
|
+ Zset: `zclear`, `mzclear`
|
||||||
|
+ Bitmap: `bclear`, `mbclear`
|
||||||
|
|
||||||
|
## Expire, Persist, and TTL
|
||||||
|
|
||||||
|
The same for Del.
|
||||||
|
|
||||||
|
+ KV: `expire`, `persist`, `ttl`
|
||||||
|
+ Hash: `hexpire`, `hpersist`, `httl`
|
||||||
|
+ List: `lexpire`, `lpersist`, `lttl`
|
||||||
|
+ Set: `sexpire`, `spersist`, `sttl`
|
||||||
|
+ Zset: `zexpire`, `zpersist`, `zttl`
|
||||||
|
+ Bitmap: `bexpire`, `bpersist`, `bttl`
|
||||||
|
|
||||||
|
## ZSet
|
||||||
|
|
||||||
|
ZSet only support int64 score, not double in Redis.
|
||||||
|
|
||||||
|
## Transaction
|
||||||
|
|
||||||
|
LedisDB supports ACID transaction using LMDB or BoltDB, maybe later it will support `multi`, `exec`, `discard`.
|
||||||
|
|
||||||
|
Transaction API:
|
||||||
|
|
||||||
|
+ `begin`
|
||||||
|
+ `commit`
|
||||||
|
+ `rollback`
|
||||||
|
|
||||||
|
## Scan
|
||||||
|
|
||||||
|
LedisDB supplies `xscan`, etc, to fetch data iteratively.
|
||||||
|
|
||||||
|
+ KV: `xscan`
|
||||||
|
+ Hash: `hxscan`
|
||||||
|
+ List: `lxscan`
|
||||||
|
+ Set: `sxscan`
|
||||||
|
+ Zset: `zxscan`
|
||||||
|
+ Bitmap: `bxscan`
|
||||||
|
|
||||||
|
|
||||||
|
Of course, LedisDB has not implemented all APIs in Redis, you can see full commands in commands.json, commands.doc or [wiki](https://github.com/siddontang/ledisdb/wiki/Commands).
|
|
@ -528,37 +528,37 @@
|
||||||
"readonly": false
|
"readonly": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"SCAN": {
|
"XSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "KV",
|
"group": "KV",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"HSCAN": {
|
"HXSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "Hash",
|
"group": "Hash",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"LSCAN": {
|
"LXSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "List",
|
"group": "List",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"SSCAN": {
|
"SXSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "Set",
|
"group": "Set",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"ZSCAN": {
|
"ZXSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "ZSet",
|
"group": "ZSet",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"BSCAN": {
|
"BXSCAN": {
|
||||||
"arguments": "key [MATCH match] [COUNT count]",
|
"arguments": "key [MATCH match] [COUNT count]",
|
||||||
"group": "Bitmap",
|
"group": "Bitmap",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
|
|
|
@ -26,7 +26,7 @@ Table of Contents
|
||||||
- [EXPIREAT key timestamp](#expireat-key-timestamp)
|
- [EXPIREAT key timestamp](#expireat-key-timestamp)
|
||||||
- [TTL key](#ttl-key)
|
- [TTL key](#ttl-key)
|
||||||
- [PERSIST key](#persist-key)
|
- [PERSIST key](#persist-key)
|
||||||
- [SCAN key [MATCH match] [COUNT count]](#scan-key-match-match-count-count)
|
- [XSCAN key [MATCH match] [COUNT count]](#xscan-key-match-match-count-count)
|
||||||
- [Hash](#hash)
|
- [Hash](#hash)
|
||||||
- [HDEL key field [field ...]](#hdel-key-field-field-)
|
- [HDEL key field [field ...]](#hdel-key-field-field-)
|
||||||
- [HEXISTS key field](#hexists-key-field)
|
- [HEXISTS key field](#hexists-key-field)
|
||||||
|
@ -45,7 +45,7 @@ Table of Contents
|
||||||
- [HEXPIREAT key timestamp](#hexpireat-key-timestamp)
|
- [HEXPIREAT key timestamp](#hexpireat-key-timestamp)
|
||||||
- [HTTL key](#httl-key)
|
- [HTTL key](#httl-key)
|
||||||
- [HPERSIST key](#hpersist-key)
|
- [HPERSIST key](#hpersist-key)
|
||||||
- [HSCAN key [MATCH match] [COUNT count]](#hscan-key-match-match-count-count)
|
- [HXSCAN key [MATCH match] [COUNT count]](#hxscan-key-match-match-count-count)
|
||||||
- [List](#list)
|
- [List](#list)
|
||||||
- [LINDEX key index](#lindex-key-index)
|
- [LINDEX key index](#lindex-key-index)
|
||||||
- [LLEN key](#llen-key)
|
- [LLEN key](#llen-key)
|
||||||
|
@ -60,7 +60,7 @@ Table of Contents
|
||||||
- [LEXPIREAT key timestamp](#lexpireat-key-timestamp)
|
- [LEXPIREAT key timestamp](#lexpireat-key-timestamp)
|
||||||
- [LTTL key](#lttl-key)
|
- [LTTL key](#lttl-key)
|
||||||
- [LPERSIST key](#lpersist-key)
|
- [LPERSIST key](#lpersist-key)
|
||||||
- [LSCAN key [MATCH match] [COUNT count]](#lscan-key-match-match-count-count)
|
- [LXSCAN key [MATCH match] [COUNT count]](#lxscan-key-match-match-count-count)
|
||||||
- [Set](#set)
|
- [Set](#set)
|
||||||
- [SADD key member [member ...]](#sadd-key-member-member-)
|
- [SADD key member [member ...]](#sadd-key-member-member-)
|
||||||
- [SCARD key](#scard-key)
|
- [SCARD key](#scard-key)
|
||||||
|
@ -79,7 +79,7 @@ Table of Contents
|
||||||
- [SEXPIREAT key timestamp](#sexpireat-key-timestamp)
|
- [SEXPIREAT key timestamp](#sexpireat-key-timestamp)
|
||||||
- [STTL key](#sttl-key)
|
- [STTL key](#sttl-key)
|
||||||
- [SPERSIST key](#spersist-key)
|
- [SPERSIST key](#spersist-key)
|
||||||
- [SSCAN key [MATCH match] [COUNT count]](#sscan-key-match-match-count-count)
|
- [SXSCAN key [MATCH match] [COUNT count]](#sxscan-key-match-match-count-count)
|
||||||
- [ZSet](#zset)
|
- [ZSet](#zset)
|
||||||
- [ZADD key score member [score member ...]](#zadd-key-score-member-score-member-)
|
- [ZADD key score member [score member ...]](#zadd-key-score-member-score-member-)
|
||||||
- [ZCARD key](#zcard-key)
|
- [ZCARD key](#zcard-key)
|
||||||
|
@ -105,7 +105,7 @@ Table of Contents
|
||||||
](#zunionstore-destination-numkeys-key-key--weights-weight-weight--aggregate-summinmax)
|
](#zunionstore-destination-numkeys-key-key--weights-weight-weight--aggregate-summinmax)
|
||||||
- [ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
|
- [ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
|
||||||
](#zinterstore-destination-numkeys-key-key--weights-weight-weight--aggregate-summinmax)
|
](#zinterstore-destination-numkeys-key-key--weights-weight-weight--aggregate-summinmax)
|
||||||
- [ZSCAN key [MATCH match] [COUNT count]](#zscan-key-match-match-count-count)
|
- [ZXSCAN key [MATCH match] [COUNT count]](#zxscan-key-match-match-count-count)
|
||||||
- [Bitmap](#bitmap)
|
- [Bitmap](#bitmap)
|
||||||
- [BGET key](#bget-key)
|
- [BGET key](#bget-key)
|
||||||
- [BGETBIT key offset](#bgetbit-key-offset)
|
- [BGETBIT key offset](#bgetbit-key-offset)
|
||||||
|
@ -117,7 +117,7 @@ Table of Contents
|
||||||
- [BEXPIREAT key timestamp](#bexpireat-key-timestamp)
|
- [BEXPIREAT key timestamp](#bexpireat-key-timestamp)
|
||||||
- [BTTL key](#bttl-key)
|
- [BTTL key](#bttl-key)
|
||||||
- [BPERSIST key](#bpersist-key)
|
- [BPERSIST key](#bpersist-key)
|
||||||
- [BSCAN key [MATCH match] [COUNT count]](#bscan-key-match-match-count-count)
|
- [BXSCAN key [MATCH match] [COUNT count]](#bxscan-key-match-match-count-count)
|
||||||
- [Replication](#replication)
|
- [Replication](#replication)
|
||||||
- [SLAVEOF host port](#slaveof-host-port)
|
- [SLAVEOF host port](#slaveof-host-port)
|
||||||
- [FULLSYNC](#fullsync)
|
- [FULLSYNC](#fullsync)
|
||||||
|
@ -469,7 +469,7 @@ ledis> TTL mykey
|
||||||
(integer) -1
|
(integer) -1
|
||||||
```
|
```
|
||||||
|
|
||||||
### SCAN key [MATCH match] [COUNT count]
|
### XSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate KV keys incrementally.
|
Iterate KV keys incrementally.
|
||||||
|
|
||||||
|
@ -490,19 +490,19 @@ ledis>set b 2
|
||||||
OK
|
OK
|
||||||
ledis>set c 3
|
ledis>set c 3
|
||||||
OK
|
OK
|
||||||
127.0.0.1:6380>scan ""
|
127.0.0.1:6380>xscan ""
|
||||||
1) ""
|
1) ""
|
||||||
2) ["a" "b" "c"]
|
2) ["a" "b" "c"]
|
||||||
ledis>scan "" count 1
|
ledis>xscan "" count 1
|
||||||
1) "a"
|
1) "a"
|
||||||
2) ["a"]
|
2) ["a"]
|
||||||
ledis>scan "a" count 1
|
ledis>xscan "a" count 1
|
||||||
1) "b"
|
1) "b"
|
||||||
2) ["b"]
|
2) ["b"]
|
||||||
ledis>scan "b" count 1
|
ledis>xscan "b" count 1
|
||||||
1) "c"
|
1) "c"
|
||||||
2) ["c"]
|
2) ["c"]
|
||||||
ledis>scan "c" count 1
|
ledis>xscan "c" count 1
|
||||||
1) ""
|
1) ""
|
||||||
2) []
|
2) []
|
||||||
```
|
```
|
||||||
|
@ -870,11 +870,11 @@ ledis> HPERSIST not_exists_key
|
||||||
(integer) 0
|
(integer) 0
|
||||||
```
|
```
|
||||||
|
|
||||||
### HSCAN key [MATCH match] [COUNT count]
|
### HXSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate Hash keys incrementally.
|
Iterate Hash keys incrementally.
|
||||||
|
|
||||||
See [Scan](#scan-key-match-match-count-count) for more information.
|
See [XSCAN](#xscan-key-match-match-count-count) for more information.
|
||||||
|
|
||||||
## List
|
## List
|
||||||
|
|
||||||
|
@ -1167,11 +1167,11 @@ ledis> LPERSIST b
|
||||||
(integer) 0
|
(integer) 0
|
||||||
```
|
```
|
||||||
|
|
||||||
### LSCAN key [MATCH match] [COUNT count]
|
### LXSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate list keys incrementally.
|
Iterate list keys incrementally.
|
||||||
|
|
||||||
See [Scan](#scan-key-match-match-count-count) for more information.
|
See [XSCAN](#xscan-key-match-match-count-count) for more information.
|
||||||
|
|
||||||
|
|
||||||
## Set
|
## Set
|
||||||
|
@ -1595,11 +1595,11 @@ ledis> STTL key
|
||||||
(integer) -1
|
(integer) -1
|
||||||
```
|
```
|
||||||
|
|
||||||
### SSCAN key [MATCH match] [COUNT count]
|
### SXSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate Set keys incrementally.
|
Iterate Set keys incrementally.
|
||||||
|
|
||||||
See [Scan](#scan-key-match-match-count-count) for more information.
|
See [XSCAN](#xscan-key-match-match-count-count) for more information.
|
||||||
|
|
||||||
|
|
||||||
## ZSet
|
## ZSet
|
||||||
|
@ -2221,11 +2221,11 @@ ledis> ZRANGE out 0 -1 WITHSCORES
|
||||||
4) "10"
|
4) "10"
|
||||||
```
|
```
|
||||||
|
|
||||||
### ZSCAN key [MATCH match] [COUNT count]
|
### ZXSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate ZSet keys incrementally.
|
Iterate ZSet keys incrementally.
|
||||||
|
|
||||||
See [Scan](#scan-key-match-match-count-count) for more information.
|
See [XSCAN](#xscan-key-match-match-count-count) for more information.
|
||||||
|
|
||||||
|
|
||||||
## Bitmap
|
## Bitmap
|
||||||
|
@ -2387,11 +2387,11 @@ ledis> BCOUNT flag 5 6
|
||||||
(refer to [PERSIST](#persist-key) api for other types)
|
(refer to [PERSIST](#persist-key) api for other types)
|
||||||
|
|
||||||
|
|
||||||
### BSCAN key [MATCH match] [COUNT count]
|
### BXSCAN key [MATCH match] [COUNT count]
|
||||||
|
|
||||||
Iterate Bitmap keys incrementally.
|
Iterate Bitmap keys incrementally.
|
||||||
|
|
||||||
See [Scan](#scan-key-match-match-count-count) for more information.
|
See [XSCAN](#xscan-key-match-match-count-count) for more information.
|
||||||
|
|
||||||
|
|
||||||
## Replication
|
## Replication
|
||||||
|
|
|
@ -272,7 +272,7 @@ func bpersistCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func bscanCommand(c *client) error {
|
func bxscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -305,5 +305,5 @@ func init() {
|
||||||
register("bexpireat", bexpireAtCommand)
|
register("bexpireat", bexpireAtCommand)
|
||||||
register("bttl", bttlCommand)
|
register("bttl", bttlCommand)
|
||||||
register("bpersist", bpersistCommand)
|
register("bpersist", bpersistCommand)
|
||||||
register("bscan", bscanCommand)
|
register("bxscan", bxscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ func hpersistCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hscanCommand(c *client) error {
|
func hxscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -334,5 +334,5 @@ func init() {
|
||||||
register("hexpireat", hexpireAtCommand)
|
register("hexpireat", hexpireAtCommand)
|
||||||
register("httl", httlCommand)
|
register("httl", httlCommand)
|
||||||
register("hpersist", hpersistCommand)
|
register("hpersist", hpersistCommand)
|
||||||
register("hscan", hscanCommand)
|
register("hxscan", hxscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,7 @@ func parseScanArgs(c *client) (key []byte, match string, count int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanCommand(c *client) error {
|
func xscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -358,5 +358,5 @@ func init() {
|
||||||
register("expireat", expireAtCommand)
|
register("expireat", expireAtCommand)
|
||||||
register("ttl", ttlCommand)
|
register("ttl", ttlCommand)
|
||||||
register("persist", persistCommand)
|
register("persist", persistCommand)
|
||||||
register("scan", scanCommand)
|
register("xscan", xscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ func lpersistCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lscanCommand(c *client) error {
|
func lxscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -266,5 +266,5 @@ func init() {
|
||||||
register("lexpireat", lexpireAtCommand)
|
register("lexpireat", lexpireAtCommand)
|
||||||
register("lttl", lttlCommand)
|
register("lttl", lttlCommand)
|
||||||
register("lpersist", lpersistCommand)
|
register("lpersist", lpersistCommand)
|
||||||
register("lscan", lscanCommand)
|
register("lxscan", lxscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,7 +262,7 @@ func spersistCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func sscanCommand(c *client) error {
|
func sxscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -301,5 +301,5 @@ func init() {
|
||||||
register("sexpireat", sexpireAtCommand)
|
register("sexpireat", sexpireAtCommand)
|
||||||
register("sttl", sttlCommand)
|
register("sttl", sttlCommand)
|
||||||
register("spersist", spersistCommand)
|
register("spersist", spersistCommand)
|
||||||
register("sscan", sscanCommand)
|
register("sxscan", sxscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -638,7 +638,7 @@ func zinterstoreCommand(c *client) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func zscanCommand(c *client) error {
|
func zxscanCommand(c *client) error {
|
||||||
key, match, count, err := parseScanArgs(c)
|
key, match, count, err := parseScanArgs(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -686,5 +686,5 @@ func init() {
|
||||||
register("zexpireat", zexpireAtCommand)
|
register("zexpireat", zexpireAtCommand)
|
||||||
register("zttl", zttlCommand)
|
register("zttl", zttlCommand)
|
||||||
register("zpersist", zpersistCommand)
|
register("zpersist", zpersistCommand)
|
||||||
register("zscan", zscanCommand)
|
register("zxscan", zxscanCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ func testKVScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "scan")
|
checkScan(t, c, "xscan")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testHashScan(t *testing.T, c *ledis.Client) {
|
func testHashScan(t *testing.T, c *ledis.Client) {
|
||||||
|
@ -94,7 +94,7 @@ func testHashScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "hscan")
|
checkScan(t, c, "hxscan")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testListScan(t *testing.T, c *ledis.Client) {
|
func testListScan(t *testing.T, c *ledis.Client) {
|
||||||
|
@ -104,7 +104,7 @@ func testListScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "lscan")
|
checkScan(t, c, "lxscan")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testZSetScan(t *testing.T, c *ledis.Client) {
|
func testZSetScan(t *testing.T, c *ledis.Client) {
|
||||||
|
@ -114,7 +114,7 @@ func testZSetScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "zscan")
|
checkScan(t, c, "zxscan")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSetScan(t *testing.T, c *ledis.Client) {
|
func testSetScan(t *testing.T, c *ledis.Client) {
|
||||||
|
@ -124,7 +124,7 @@ func testSetScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "sscan")
|
checkScan(t, c, "sxscan")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBitScan(t *testing.T, c *ledis.Client) {
|
func testBitScan(t *testing.T, c *ledis.Client) {
|
||||||
|
@ -134,5 +134,5 @@ func testBitScan(t *testing.T, c *ledis.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkScan(t, c, "bscan")
|
checkScan(t, c, "bxscan")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue