mirror of https://github.com/ledisdb/ledisdb.git
Merge pull request #99 from holys/develop
add SETEX command support for the KV data structure
This commit is contained in:
commit
c3ca5bba14
|
@ -1,4 +1,4 @@
|
||||||
//This file was generated by .tools/generate_commands.py on Mon Oct 20 2014 22:35:33 +0800
|
//This file was generated by .tools/generate_commands.py on Sun Oct 26 2014 15:14:39 +0800
|
||||||
package main
|
package main
|
||||||
|
|
||||||
var helpCommands = [][]string{
|
var helpCommands = [][]string{
|
||||||
|
@ -86,6 +86,7 @@ var helpCommands = [][]string{
|
||||||
{"SDIFFSTORE", "destination key [key ...]", "Set"},
|
{"SDIFFSTORE", "destination key [key ...]", "Set"},
|
||||||
{"SELECT", "index", "Server"},
|
{"SELECT", "index", "Server"},
|
||||||
{"SET", "key value", "KV"},
|
{"SET", "key value", "KV"},
|
||||||
|
{"SETEX", "key seconds value", "KV"},
|
||||||
{"SETNX", "key value", "KV"},
|
{"SETNX", "key value", "KV"},
|
||||||
{"SEXPIRE", "key seconds", "Set"},
|
{"SEXPIRE", "key seconds", "Set"},
|
||||||
{"SEXPIREAT", "key timestamp", "Set"},
|
{"SEXPIREAT", "key timestamp", "Set"},
|
||||||
|
|
|
@ -310,6 +310,11 @@
|
||||||
"group": "KV",
|
"group": "KV",
|
||||||
"readonly": false
|
"readonly": false
|
||||||
},
|
},
|
||||||
|
"SETEX": {
|
||||||
|
"arguments": "key seconds value",
|
||||||
|
"group": "KV",
|
||||||
|
"readonly": false
|
||||||
|
},
|
||||||
"SLAVEOF": {
|
"SLAVEOF": {
|
||||||
"arguments": "host port [RESTART] [READONLY]",
|
"arguments": "host port [RESTART] [READONLY]",
|
||||||
"group": "Replication",
|
"group": "Replication",
|
||||||
|
|
|
@ -22,6 +22,7 @@ Table of Contents
|
||||||
- [MSET key value [key value ...]](#mset-key-value-key-value-)
|
- [MSET key value [key value ...]](#mset-key-value-key-value-)
|
||||||
- [SET key value](#set-key-value)
|
- [SET key value](#set-key-value)
|
||||||
- [SETNX key value](#setnx-key-value)
|
- [SETNX key value](#setnx-key-value)
|
||||||
|
- [SETEX key seconds value](#setex-key-seconds-value)
|
||||||
- [EXPIRE key seconds](#expire-key-seconds)
|
- [EXPIRE key seconds](#expire-key-seconds)
|
||||||
- [EXPIREAT key timestamp](#expireat-key-timestamp)
|
- [EXPIREAT key timestamp](#expireat-key-timestamp)
|
||||||
- [TTL key](#ttl-key)
|
- [TTL key](#ttl-key)
|
||||||
|
@ -389,6 +390,30 @@ ledis> GET mykey
|
||||||
"hello"
|
"hello"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### SETEX key seconds value
|
||||||
|
Set key to hold the string value and set key to timeout after a given number of seconds. This command is equivalent to executing the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
SET mykey value
|
||||||
|
EXPIRE mykey seconds
|
||||||
|
```
|
||||||
|
|
||||||
|
**Return value**
|
||||||
|
|
||||||
|
Simple string reply
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```
|
||||||
|
ledis> SETEX mykey 10 "Hello"
|
||||||
|
OK
|
||||||
|
ledis> TTL mykey
|
||||||
|
(integer) 10
|
||||||
|
ledis> GET mykey
|
||||||
|
"Hello"
|
||||||
|
ledis>
|
||||||
|
```
|
||||||
|
|
||||||
### EXPIRE key seconds
|
### EXPIRE key seconds
|
||||||
|
|
||||||
Set a timeout on key. After the timeout has expired, the key will be deleted.
|
Set a timeout on key. After the timeout has expired, the key will be deleted.
|
||||||
|
|
|
@ -300,6 +300,32 @@ func (db *DB) SetNX(key []byte, value []byte) (int64, error) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) SetEX(key []byte, duration int64, value []byte) error {
|
||||||
|
if err := checkKeySize(key); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := checkValueSize(value); err != nil {
|
||||||
|
return err
|
||||||
|
} else if duration <= 0 {
|
||||||
|
return errExpireValue
|
||||||
|
}
|
||||||
|
|
||||||
|
ek := db.encodeKVKey(key)
|
||||||
|
|
||||||
|
t := db.kvBatch
|
||||||
|
|
||||||
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
|
||||||
|
t.Put(ek, value)
|
||||||
|
db.expireAt(t, KVType, key, time.Now().Unix()+duration)
|
||||||
|
|
||||||
|
if err := t.Commit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) flush() (drop int64, err error) {
|
func (db *DB) flush() (drop int64, err error) {
|
||||||
t := db.kvBatch
|
t := db.kvBatch
|
||||||
t.Lock()
|
t.Lock()
|
||||||
|
|
|
@ -116,3 +116,32 @@ func TestKVFlush(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestKVSetEX(t *testing.T) {
|
||||||
|
db := getTestDB()
|
||||||
|
db.FlushAll()
|
||||||
|
|
||||||
|
key := []byte("testdb_kv_c")
|
||||||
|
|
||||||
|
if err := db.SetEX(key, 10, []byte("hello world")); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := db.Get(key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if string(v) == "" {
|
||||||
|
t.Fatal("v is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if n, err := db.TTL(key); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if n != 10 {
|
||||||
|
t.Fatal(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, _ := db.Get(key); string(v) != "hello world" {
|
||||||
|
t.Fatal(string(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -66,6 +66,26 @@ func setnxCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setexCommand(c *client) error {
|
||||||
|
args := c.args
|
||||||
|
if len(args) != 3 {
|
||||||
|
return ErrCmdParams
|
||||||
|
}
|
||||||
|
|
||||||
|
sec, err := ledis.StrInt64(args[1], nil)
|
||||||
|
if err != nil {
|
||||||
|
return ErrValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.db.SetEX(args[0], sec, args[2]); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
c.resp.writeStatus(OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func existsCommand(c *client) error {
|
func existsCommand(c *client) error {
|
||||||
args := c.args
|
args := c.args
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
|
@ -365,6 +385,7 @@ func init() {
|
||||||
register("mset", msetCommand)
|
register("mset", msetCommand)
|
||||||
register("set", setCommand)
|
register("set", setCommand)
|
||||||
register("setnx", setnxCommand)
|
register("setnx", setnxCommand)
|
||||||
|
register("setex", setexCommand)
|
||||||
register("expire", expireCommand)
|
register("expire", expireCommand)
|
||||||
register("expireat", expireAtCommand)
|
register("expireat", expireAtCommand)
|
||||||
register("ttl", ttlCommand)
|
register("ttl", ttlCommand)
|
||||||
|
|
|
@ -27,6 +27,12 @@ func TestKV(t *testing.T) {
|
||||||
t.Fatal(n)
|
t.Fatal(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ok, err := ledis.String(c.Do("setex", "xx", 10, "hello world")); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if ok != OK {
|
||||||
|
t.Fatal(ok)
|
||||||
|
}
|
||||||
|
|
||||||
if v, err := ledis.String(c.Do("get", "a")); err != nil {
|
if v, err := ledis.String(c.Do("get", "a")); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
} else if v != "1234" {
|
} else if v != "1234" {
|
||||||
|
@ -214,4 +220,8 @@ func TestKVErrorParams(t *testing.T) {
|
||||||
t.Fatal("invalid err of %v", err)
|
t.Fatal("invalid err of %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := c.Do("setex", "a", "blah", "hello world"); err == nil {
|
||||||
|
t.Fatalf("invalid err %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue