Skip to content

Commit

Permalink
Support ttl in hash
Browse files Browse the repository at this point in the history
  • Loading branch information
heka1024 committed Mar 31, 2024
1 parent 35e9276 commit a030c29
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
false == limiter.exceeded? # => GET "limiter"
```

Lists, unique lists, sets, and ordered sets support expiration:
Lists, unique lists, sets, ordered sets, and hashes support expiration:

```ruby
set = Kredis.set "myset", expires_in: 1.second
Expand Down
4 changes: 2 additions & 2 deletions lib/kredis/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def kredis_limiter(name, limit:, key: nil, config: :shared, after_change: nil, e
kredis_connection_with __method__, name, key, limit: limit, config: config, after_change: after_change, expires_in: expires_in
end

def kredis_hash(name, key: nil, default: nil, typed: :string, config: :shared, after_change: nil)
kredis_connection_with __method__, name, key, default: default, typed: typed, config: config, after_change: after_change
def kredis_hash(name, key: nil, default: nil, typed: :string, config: :shared, after_change: nil, expires_in: nil)
kredis_connection_with __method__, name, key, default: default, typed: typed, config: config, after_change: after_change, expires_in: expires_in
end

def kredis_boolean(name, key: nil, default: nil, config: :shared, after_change: nil, expires_in: nil)
Expand Down
4 changes: 2 additions & 2 deletions lib/kredis/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ def enum(key, values:, default:, config: :shared, after_change: nil)
type_from(Enum, config, key, after_change: after_change, values: values, default: default)
end

def hash(key, typed: :string, default: nil, config: :shared, after_change: nil)
type_from(Hash, config, key, after_change: after_change, default: default, typed: typed)
def hash(key, typed: :string, default: nil, config: :shared, after_change: nil, expires_in: nil)
type_from(Hash, config, key, after_change: after_change, default: default, typed: typed, expires_in: expires_in)
end

def list(key, default: nil, typed: :string, config: :shared, after_change: nil, expires_in: nil)
Expand Down
5 changes: 4 additions & 1 deletion lib/kredis/types/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class Kredis::Types::Hash < Kredis::Types::Proxying
prepend Kredis::DefaultValues
include Kredis::Expiration

proxying :hget, :hset, :hmget, :hdel, :hgetall, :hkeys, :hvals, :del, :exists?

Expand All @@ -18,7 +19,9 @@ def []=(key, value)
end

def update(**entries)
hset entries.transform_values { |val| type_to_string(val, typed) } if entries.flatten.any?
with_expiration do
hset entries.transform_values { |val| type_to_string(val, typed) } if entries.flatten.any?
end
end

def values_at(*keys)
Expand Down
9 changes: 9 additions & 0 deletions test/attributes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Person
kredis_string :temporary_password, expires_in: 1.second
kredis_hash :high_scores, typed: :integer
kredis_hash :high_scores_with_default_via_lambda, typed: :integer, default: ->(p) { { high_score: JSON.parse(p.scores).max } }
kredis_hash :high_scores_with_ttl, typed: :integer, expires_in: 1.second
kredis_boolean :onboarded
kredis_boolean :adult_with_default_via_lambda, default: ->(p) { Date.today.year - p.birthdate.year >= 18 }
kredis_limiter :update_limit, limit: 3, expires_in: 1.second
Expand Down Expand Up @@ -404,6 +405,14 @@ class AttributesTest < ActiveSupport::TestCase
assert_equal({ "high_score" => 28 }, @person.high_scores_with_default_via_lambda.to_h)
end

test "hash with ttl" do
@person.high_scores_with_ttl.update(the_lost_viking: 99)
assert_equal({ "the_lost_viking" => 99 }, @person.high_scores_with_ttl.to_h)

sleep 1.1
assert_equal({}, @person.high_scores_with_ttl.to_h)
end

test "boolean" do
@person.onboarded.value = true
assert @person.onboarded.value
Expand Down
10 changes: 10 additions & 0 deletions test/types/hash_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,14 @@ class HashTest < ActiveSupport::TestCase
@hash = Kredis.hash "myhash", typed: :integer, default: ->() { { space_invaders: "100", pong: "42" } }
assert_equal({ "space_invaders" => 100, "pong" => 42 }, @hash.to_h)
end

test "support ttl" do
@hash = Kredis.hash "myhash", expires_in: 1.second
@hash[:key] = :value
@hash.update("key2" => "value2", "key3" => "value3")
assert_equal "value", @hash[:key]

sleep 1.1
assert_equal [], @hash.keys
end
end

0 comments on commit a030c29

Please sign in to comment.