Skip to content

Commit

Permalink
tidwall#102: returns ttl together with value
Browse files Browse the repository at this point in the history
  • Loading branch information
kcmvp committed May 17, 2023
1 parent 4ac2e32 commit 1c9bf46
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
19 changes: 19 additions & 0 deletions buntdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,25 @@ func (tx *Tx) Get(key string, ignoreExpired ...bool) (val string, err error) {
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
// does not exist or if the item has expired then ErrNotFound is returned.
//
Expand Down
58 changes: 58 additions & 0 deletions buntdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
db := testOpen(t)
defer testClose(db)
Expand Down

0 comments on commit 1c9bf46

Please sign in to comment.