redis_hash 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/redis_hash.rb +5 -3
- data/lib/redis_hash/base.rb +37 -0
- data/lib/redis_hash/concerns/accessors.rb +43 -0
- data/lib/redis_hash/concerns/adapter.rb +36 -0
- data/lib/redis_hash/concerns/callbacks.rb +13 -0
- data/lib/redis_hash/concerns/comparisons.rb +17 -0
- data/lib/redis_hash/concerns/converters.rb +21 -0
- data/lib/redis_hash/concerns/core.rb +15 -0
- data/lib/redis_hash/concerns/counters.rb +32 -0
- data/lib/redis_hash/concerns/default.rb +55 -0
- data/lib/redis_hash/concerns/deletions.rb +31 -0
- data/lib/redis_hash/concerns/enumerators.rb +50 -0
- data/lib/redis_hash/concerns/expiration.rb +37 -0
- data/lib/redis_hash/concerns/identity.rb +25 -0
- data/lib/redis_hash/concerns/insertions.rb +41 -0
- data/lib/redis_hash/concerns/mutations.rb +22 -0
- data/lib/redis_hash/concerns/predicates.rb +34 -0
- data/lib/redis_hash/version.rb +1 -1
- metadata +17 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3131d41ea67e65aa544a9ebdb7da08c0b0611a0f1439715af115e8c33ff9c96
|
4
|
+
data.tar.gz: 3dc68b7eaf87c5730073d4f4eb71c64d7369220f9c334e7d89fe495a1b4538af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a636758a36b3167865640201ac84227360d441be44b441ea17586681ed7167145b31e3e0d497783ee770840de87c3ed9b6aea58c483da140d39581a6beb0e315
|
7
|
+
data.tar.gz: f8c94d4d75e2c9bbc17a658d66c898dfb863955360779e5480973f9f5dd810124a513e5fc9af56dc0194d819c4da3d45118e7d9d5809662992d4e3ba92b61473
|
data/lib/redis_hash.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "concerns/adapter"
|
4
|
+
require_relative "concerns/default"
|
5
|
+
require_relative "concerns/callbacks"
|
6
|
+
require_relative "concerns/core"
|
7
|
+
require_relative "concerns/identity"
|
8
|
+
require_relative "concerns/accessors"
|
9
|
+
require_relative "concerns/comparisons"
|
10
|
+
require_relative "concerns/predicates"
|
11
|
+
require_relative "concerns/insertions"
|
12
|
+
require_relative "concerns/deletions"
|
13
|
+
require_relative "concerns/enumerators"
|
14
|
+
require_relative "concerns/mutations"
|
15
|
+
require_relative "concerns/converters"
|
16
|
+
require_relative "concerns/counters"
|
17
|
+
require_relative "concerns/expiration"
|
18
|
+
|
19
|
+
module RedisHash
|
20
|
+
class Base
|
21
|
+
include RedisHash::Adapter
|
22
|
+
include RedisHash::Default
|
23
|
+
include RedisHash::Callbacks
|
24
|
+
include RedisHash::Core
|
25
|
+
include RedisHash::Identity
|
26
|
+
include RedisHash::Accessors
|
27
|
+
include RedisHash::Comparisons
|
28
|
+
include RedisHash::Predicates
|
29
|
+
include RedisHash::Insertions
|
30
|
+
include RedisHash::Deletions
|
31
|
+
include RedisHash::Enumerators
|
32
|
+
include RedisHash::Mutations
|
33
|
+
include RedisHash::Converters
|
34
|
+
include RedisHash::Counters
|
35
|
+
include RedisHash::Expiration
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Accessors allow for the retrieval of data from the Hash.
|
4
|
+
module RedisHash
|
5
|
+
module Accessors
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :hget, :hkeys, :hlen, :hmget, :hvals, to: :redis
|
10
|
+
delegate :assoc, :compact, :dig, :fetch_values, :flatten, :key, :rassoc, :rehash, to: :to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](field)
|
14
|
+
hget(redis_key, field) || default(field)
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(field, default = nil)
|
18
|
+
value = self[field]
|
19
|
+
return value if value.present?
|
20
|
+
return yield(field) if block_given?
|
21
|
+
return default unless default.nil?
|
22
|
+
|
23
|
+
raise KeyError, "key not found: \"#{field}\""
|
24
|
+
end
|
25
|
+
|
26
|
+
def keys
|
27
|
+
hkeys(redis_key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def length
|
31
|
+
hlen(redis_key)
|
32
|
+
end
|
33
|
+
alias_method :size, :length
|
34
|
+
|
35
|
+
def values
|
36
|
+
hvals(redis_key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def values_at(*fields)
|
40
|
+
hmget(*fields.flatten.unshift(redis_key))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Adapter which handles the storage and retrieval of hash data in Redis.
|
4
|
+
module RedisHash
|
5
|
+
module Adapter
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_reader :redis, :redis_key, :redis_ttl
|
10
|
+
|
11
|
+
delegate :default_redis, :default_redis_key, :default_redis_ttl, to: :class
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def initialize_redis(redis, redis_key, redis_ttl)
|
16
|
+
@redis = redis || default_redis
|
17
|
+
@redis_key = redis_key || default_redis_key
|
18
|
+
@redis_ttl = redis_ttl || default_redis_ttl
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class_methods do
|
23
|
+
def default_redis
|
24
|
+
Redis.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_redis_key
|
28
|
+
SecureRandom.hex
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_redis_ttl
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Callbacks provide an extensible mechanism for hooking into a RedisHash.
|
4
|
+
module RedisHash
|
5
|
+
module Callbacks
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
include ActiveSupport::Callbacks
|
10
|
+
define_callbacks :initialize, :insertion, :deletion
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Comparisons encompasses equality and set inclusion.
|
4
|
+
module RedisHash
|
5
|
+
module Comparisons
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :<, :<=, :>, :>=, :compare_by_identity, :compare_by_identity?, to: :to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def eql?(other)
|
13
|
+
other.hash == hash
|
14
|
+
end
|
15
|
+
alias_method :==, :eql?
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Converters allow for other objects to be coerced into a RedisHash.
|
4
|
+
module RedisHash
|
5
|
+
module Converters
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def [](*arguments)
|
10
|
+
options = block_given? ? yield({}) : {}
|
11
|
+
new(**options).merge!(Hash[*arguments])
|
12
|
+
end
|
13
|
+
|
14
|
+
def try_convert(object, &block)
|
15
|
+
return object if object.is_a?(RedisHash)
|
16
|
+
|
17
|
+
self[object, &block] if object.respond_to?(:to_hash)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A RedisHash is a wrapper around a h<key> stored in Redis.
|
4
|
+
module RedisHash
|
5
|
+
module Core
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def initialize(default = nil, redis: nil, redis_key: nil, redis_ttl: nil, &block)
|
9
|
+
run_callbacks(:initialize) do
|
10
|
+
initialize_default(default, &block)
|
11
|
+
initialize_redis(redis, redis_key, redis_ttl)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Counters allow for the incrementing and decrementing of numeric values into the RedisHash.
|
4
|
+
module RedisHash
|
5
|
+
module Counters
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :hincrby, :hincrbyfloat, to: :redis
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def increment_field_by(field, by, modifier: 1)
|
14
|
+
raise ArgumentError, "by must be greater than or equal to 0" if by < 0
|
15
|
+
|
16
|
+
by *= modifier
|
17
|
+
|
18
|
+
return hincrbyfloat(redis_key, field, by) if by.is_a?(Float)
|
19
|
+
|
20
|
+
hincrby(redis_key, field, by)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def increment(field, by: 1)
|
25
|
+
increment_field_by(field, by)
|
26
|
+
end
|
27
|
+
|
28
|
+
def decrement(field, by: 1)
|
29
|
+
increment_field_by(field, by, modifier: -1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A Default allows a static or procedurally generated value to be returned on failed lookups.
|
4
|
+
module RedisHash
|
5
|
+
module Default
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_reader :default_proc
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def initialize_default(default, &block)
|
14
|
+
raise ArgumentError, "cannot specify both block and static default" if block_given? && default.present?
|
15
|
+
|
16
|
+
set_default(default, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_default(default, &block)
|
20
|
+
self.default = default if default.present?
|
21
|
+
self.default_proc = block if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_default(field = nil, allow_nil_field: true)
|
25
|
+
@default.presence || (default_proc&.call(self, field) if !field.nil? || allow_nil_field)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_proc(proc)
|
29
|
+
raise TypeError, "wrong default_proc type #{proc.class.name} (expected Proc)" unless proc.is_a? Proc
|
30
|
+
|
31
|
+
validate_lambda_arity(proc.arity) if proc.lambda?
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_lambda_arity(arity)
|
35
|
+
raise TypeError, "default_proc takes two arguments (2 for #{arity})" if arity >= 0 && arity != 2
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def default=(value)
|
40
|
+
@default = value
|
41
|
+
@default_proc = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_proc=(value)
|
45
|
+
validate_proc(value) unless value.nil?
|
46
|
+
|
47
|
+
@default = nil
|
48
|
+
@default_proc = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def default(field = nil)
|
52
|
+
to_default(field, allow_nil_field: false)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Deletions allow for the removal of data from the Hash.
|
4
|
+
module RedisHash
|
5
|
+
module Deletions
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :del, :hdel, to: :redis
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear
|
13
|
+
del(redis_key) and {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(field)
|
17
|
+
run_callbacks(:deletion) do
|
18
|
+
value = self[field]
|
19
|
+
result = hdel(redis_key, field)
|
20
|
+
(result == 0 && block_given?) ? yield(field) : value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def shift
|
25
|
+
return to_default if empty?
|
26
|
+
|
27
|
+
field = keys.first
|
28
|
+
[ field, delete(field) ]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Enumerators allow for the traversal and manipulation of data in the Hash.
|
4
|
+
module RedisHash
|
5
|
+
module Enumerators
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :each, :each_pair, :each_key, :each_value, :reject, :select, :transform_values, to: :to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_if
|
13
|
+
return enum_for(__method__) unless block_given?
|
14
|
+
|
15
|
+
each { |field, value| delete(field) if yield(field, value) }
|
16
|
+
|
17
|
+
to_h
|
18
|
+
end
|
19
|
+
|
20
|
+
def keep_if
|
21
|
+
return enum_for(__method__) unless block_given?
|
22
|
+
|
23
|
+
delete_if { |field, value| !yield(field, value) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def reject!(&block)
|
27
|
+
return enum_for(__method__) unless block_given?
|
28
|
+
|
29
|
+
original = to_h
|
30
|
+
delete_if(&block)
|
31
|
+
current = to_h
|
32
|
+
|
33
|
+
(original == current) ? nil : current
|
34
|
+
end
|
35
|
+
|
36
|
+
def select!
|
37
|
+
return enum_for(__method__) unless block_given?
|
38
|
+
|
39
|
+
reject! { |*arguments| !yield(*arguments) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def transform_values!
|
43
|
+
return enum_for(__method__) unless block_given?
|
44
|
+
|
45
|
+
each { |field, value| store(field, yield(value)) }
|
46
|
+
|
47
|
+
to_h
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Expiration ensures that volatile hashes are properly configured to expire in Redis.
|
4
|
+
module RedisHash
|
5
|
+
module Expiration
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
set_callback :insertion, :before, :before_insertion
|
10
|
+
set_callback :insertion, :after, :after_insertion
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_writer :was_empty_before_insertion
|
15
|
+
|
16
|
+
def before_insertion
|
17
|
+
self.was_empty_before_insertion = empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_insertion
|
21
|
+
expire(redis_ttl) if redis_ttl.present? && empty_before_insertion?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def empty_before_insertion?
|
26
|
+
@was_empty_before_insertion.present?
|
27
|
+
end
|
28
|
+
|
29
|
+
def expire(seconds)
|
30
|
+
redis.expire(redis_key, seconds)
|
31
|
+
end
|
32
|
+
|
33
|
+
def ttl
|
34
|
+
redis.ttl(redis_key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Identity relates to the specific object instance.
|
4
|
+
module RedisHash
|
5
|
+
module Identity
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :hgetall, to: :redis
|
10
|
+
delegate :inspect, :to_proc, :to_s, to: :to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash
|
14
|
+
{ redis_id: redis.id, redis_key: redis_key }.hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
hgetall(redis_key)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Insertions allow for the addition of data into the RedisHash.
|
4
|
+
module RedisHash
|
5
|
+
module Insertions
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :hmset, :hset, :hsetnx, to: :redis
|
10
|
+
delegate :merge, to: :to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def merge!(other_hash)
|
14
|
+
run_callbacks(:insertion) { hmset(*other_hash.to_a.unshift(redis_key)) }
|
15
|
+
|
16
|
+
self
|
17
|
+
end
|
18
|
+
alias_method :update, :merge!
|
19
|
+
|
20
|
+
def store(field, value)
|
21
|
+
run_callbacks(:insertion) { hset(redis_key, field, value) }
|
22
|
+
end
|
23
|
+
alias_method :[]=, :store
|
24
|
+
|
25
|
+
def setnx!(field, value)
|
26
|
+
run_callbacks(:insertion) do
|
27
|
+
success = hsetnx(redis_key, field, value)
|
28
|
+
|
29
|
+
raise RedisHash::AlreadyDefinedError, "#{field} already defined" unless success
|
30
|
+
end
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def setnx(field, value)
|
36
|
+
setnx!(field, value)
|
37
|
+
rescue RedisHash::AlreadyDefinedError
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Mutations allow for the manipulation of data in the Hash.
|
4
|
+
module RedisHash
|
5
|
+
module Mutations
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def compact!
|
9
|
+
delete_if { |_, value| value.blank? }
|
10
|
+
end
|
11
|
+
|
12
|
+
def invert
|
13
|
+
inversion = to_h.invert
|
14
|
+
clear
|
15
|
+
inversion.each { |key, value| self[key] = value }
|
16
|
+
end
|
17
|
+
|
18
|
+
def replace(other_hash)
|
19
|
+
clear and merge!(other_hash)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Predicates enable querying the Hash for data.
|
4
|
+
module RedisHash
|
5
|
+
module Predicates
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
delegate :hexists, to: :redis
|
10
|
+
end
|
11
|
+
|
12
|
+
def any?(&block)
|
13
|
+
return length > 0 unless block_given?
|
14
|
+
|
15
|
+
to_h.any?(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def empty?
|
19
|
+
length == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def include?(field)
|
23
|
+
hexists(redis_key, field)
|
24
|
+
end
|
25
|
+
alias_method :has_key?, :include?
|
26
|
+
alias_method :key?, :include?
|
27
|
+
alias_method :member?, :include?
|
28
|
+
|
29
|
+
def value?(value)
|
30
|
+
values.include? value
|
31
|
+
end
|
32
|
+
alias_method :has_value?, :value?
|
33
|
+
end
|
34
|
+
end
|
data/lib/redis_hash/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Garside
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 5.2.1
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: technologic
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.9.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.9.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: redis
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,6 +49,22 @@ files:
|
|
63
49
|
- LICENSE.txt
|
64
50
|
- README.md
|
65
51
|
- lib/redis_hash.rb
|
52
|
+
- lib/redis_hash/base.rb
|
53
|
+
- lib/redis_hash/concerns/accessors.rb
|
54
|
+
- lib/redis_hash/concerns/adapter.rb
|
55
|
+
- lib/redis_hash/concerns/callbacks.rb
|
56
|
+
- lib/redis_hash/concerns/comparisons.rb
|
57
|
+
- lib/redis_hash/concerns/converters.rb
|
58
|
+
- lib/redis_hash/concerns/core.rb
|
59
|
+
- lib/redis_hash/concerns/counters.rb
|
60
|
+
- lib/redis_hash/concerns/default.rb
|
61
|
+
- lib/redis_hash/concerns/deletions.rb
|
62
|
+
- lib/redis_hash/concerns/enumerators.rb
|
63
|
+
- lib/redis_hash/concerns/expiration.rb
|
64
|
+
- lib/redis_hash/concerns/identity.rb
|
65
|
+
- lib/redis_hash/concerns/insertions.rb
|
66
|
+
- lib/redis_hash/concerns/mutations.rb
|
67
|
+
- lib/redis_hash/concerns/predicates.rb
|
66
68
|
- lib/redis_hash/version.rb
|
67
69
|
homepage: https://github.com/Freshly/spicerack/tree/master/redis_hash
|
68
70
|
licenses:
|