mirror of https://github.com/tidwall/buntdb.git
#102: returns ttl together with value
This commit is contained in:
parent
4ac2e321b1
commit
1c9bf46244
19
buntdb.go
19
buntdb.go
|
@ -1563,6 +1563,25 @@ func (tx *Tx) Get(key string, ignoreExpired ...bool) (val string, err error) {
|
||||||
return item.val, nil
|
return item.val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWithTTL returns a value for a key together with it's TTL.
|
||||||
|
// If the item does not exist or if the item has expired then ErrNotFound is returned.
|
||||||
|
// A negative duration will be returned for items that do not have an expiration.
|
||||||
|
func (tx *Tx) GetWithTTL(key string) (string, time.Duration, error) {
|
||||||
|
if tx.db == nil {
|
||||||
|
return "", 0, ErrTxClosed
|
||||||
|
}
|
||||||
|
item := tx.db.get(key)
|
||||||
|
if item == nil || item.expired() {
|
||||||
|
return "", 0, ErrNotFound
|
||||||
|
} else if item.opts == nil || !item.opts.ex {
|
||||||
|
return item.val, -1, nil
|
||||||
|
} else if ttl := time.Until(item.opts.exat); ttl < 0 {
|
||||||
|
return "", 0, ErrNotFound
|
||||||
|
} else {
|
||||||
|
return item.val, ttl, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delete removes an item from the database based on the item's key. If the item
|
// Delete removes an item from the database based on the item's key. If the item
|
||||||
// does not exist or if the item has expired then ErrNotFound is returned.
|
// does not exist or if the item has expired then ErrNotFound is returned.
|
||||||
//
|
//
|
||||||
|
|
|
@ -2193,6 +2193,64 @@ func TestTTLReOpen(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetWithTTL(t *testing.T) {
|
||||||
|
db := testOpen(t)
|
||||||
|
defer testClose(db)
|
||||||
|
err := db.Update(func(tx *Tx) error {
|
||||||
|
if _, _, err := tx.Set("key1", "val1", &SetOptions{Expires: true, TTL: time.Second}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, _, err := tx.Set("key2", "val2", nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = db.View(func(tx *Tx) error {
|
||||||
|
v, dur1, err := tx.GetWithTTL("key1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if v != "val1" {
|
||||||
|
t.Fatalf("expected [%v], got [%v]", "val1", v)
|
||||||
|
}
|
||||||
|
if dur1 > time.Second || dur1 <= 0 {
|
||||||
|
t.Fatalf("expecting between zero and one second, got '%v'", dur1)
|
||||||
|
}
|
||||||
|
v, dur1, err = tx.GetWithTTL("key2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if dur1 >= 0 {
|
||||||
|
t.Fatalf("expecting a negative value, got '%v'", dur1)
|
||||||
|
}
|
||||||
|
if v != "val2" {
|
||||||
|
t.Fatalf("expected [%v], got [%v]", "val2", v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
db.View(func(tx *Tx) error {
|
||||||
|
v, dur1, err := tx.GetWithTTL("key1")
|
||||||
|
if err != ErrNotFound {
|
||||||
|
t.Fatalf("expecting ErrNotFound error")
|
||||||
|
}
|
||||||
|
if v != "" {
|
||||||
|
t.Fatalf("expected '', got [%v]", v)
|
||||||
|
}
|
||||||
|
if dur1 != 0 {
|
||||||
|
t.Fatalf("expecting 0, got '%v'", dur1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestTTL(t *testing.T) {
|
func TestTTL(t *testing.T) {
|
||||||
db := testOpen(t)
|
db := testOpen(t)
|
||||||
defer testClose(db)
|
defer testClose(db)
|
||||||
|
|
Loading…
Reference in New Issue