#102: returns ttl together with value

This commit is contained in:
kcmvp 2023-05-18 00:41:03 +08:00
parent 4ac2e321b1
commit 1c9bf46244
2 changed files with 77 additions and 0 deletions

View File

@ -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.
// //

View File

@ -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)