kredis 1.0.1 → 1.3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -6
- data/lib/kredis/attributes.rb +7 -2
- data/lib/kredis/migration.rb +14 -8
- data/lib/kredis/type/json.rb +1 -1
- data/lib/kredis/types/callbacks_proxy.rb +3 -2
- data/lib/kredis/types/counter.rb +2 -2
- data/lib/kredis/types/enum.rb +1 -0
- data/lib/kredis/types/hash.rb +1 -0
- data/lib/kredis/types/list.rb +5 -1
- data/lib/kredis/types/proxy.rb +14 -3
- data/lib/kredis/types/proxying.rb +2 -2
- data/lib/kredis/types/slots.rb +13 -4
- data/lib/kredis/types/unique_list.rb +8 -2
- data/lib/kredis/version.rb +1 -1
- data/lib/kredis.rb +1 -0
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6042f4320cf89f8b0eae1ce4c8daa61ee6821775b7fdeab02777673a25b2cba1
|
4
|
+
data.tar.gz: 67121a89444ffd7f8e0a1636fc6651a2851bbc5b63514a23413136bca2abd22d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81888671af0fb781788d890640142da0f36bf03589d628ec2aaeca1d86608d9602282a9b9955e0c496cd47be01d4f4e3e42d47ac9d9414949ca635c2768177b8
|
7
|
+
data.tar.gz: eb7f0f1896bf2c27c4fa5630d43db65c8fcf183de9be5709146a3d06d183afdc33873f705a57dbbea5c58c2ca826758a82bd84ef81dfd320ca1d2a5c1c5eef1a
|
data/README.md
CHANGED
@@ -109,8 +109,10 @@ enum = Kredis.enum "myenum", values: %w[ one two three ], default: "one"
|
|
109
109
|
true == enum.one? # => GET myenum
|
110
110
|
enum.value = "two" # => SET myenum "two"
|
111
111
|
"two" == enum.value # => GET myenum
|
112
|
+
enum.three! # => SET myenum "three"
|
113
|
+
"three" == enum.value # => GET myenum
|
112
114
|
enum.value = "four"
|
113
|
-
"
|
115
|
+
"three" == enum.value # => GET myenum
|
114
116
|
enum.reset # => DEL myenum
|
115
117
|
"one" == enum.value # => GET myenum
|
116
118
|
|
@@ -168,9 +170,16 @@ You can use all these structures in models:
|
|
168
170
|
```ruby
|
169
171
|
class Person < ApplicationRecord
|
170
172
|
kredis_list :names
|
171
|
-
kredis_list :
|
173
|
+
kredis_list :names_with_custom_key_via_lambda, key: ->(p) { "person:#{p.id}:names_customized" }
|
174
|
+
kredis_list :names_with_custom_key_via_method, key: :generate_names_key
|
172
175
|
kredis_unique_list :skills, limit: 2
|
173
176
|
kredis_enum :morning, values: %w[ bright blue black ], default: "bright"
|
177
|
+
kredis_counter :steps, expires_in: 1.hour
|
178
|
+
|
179
|
+
private
|
180
|
+
def generate_names_key
|
181
|
+
"key-generated-from-private-method"
|
182
|
+
end
|
174
183
|
end
|
175
184
|
|
176
185
|
person = Person.find(5)
|
@@ -194,14 +203,17 @@ end
|
|
194
203
|
|
195
204
|
## Installation
|
196
205
|
|
197
|
-
1.
|
198
|
-
2. Run `./bin/
|
199
|
-
3. Run `./bin/rails kredis:install` to add a default configuration at [`config/redis/shared.yml`](lib/install/shared.yml)
|
206
|
+
1. Run `./bin/bundle add kredis`
|
207
|
+
2. Run `./bin/rails kredis:install` to add a default configuration at [`config/redis/shared.yml`](lib/install/shared.yml)
|
200
208
|
|
201
209
|
Additional configurations can be added under `config/redis/*.yml` and referenced when a type is created. For example, `Kredis.string("mystring", config: :strings)` would lookup `config/redis/strings.yml`.
|
202
210
|
|
203
211
|
Kredis passes the configuration to `Redis.new` to establish the connection. See the [Redis documentation](https://github.com/redis/redis-rb) for other configuration options.
|
204
212
|
|
213
|
+
### Redis support
|
214
|
+
|
215
|
+
Kredis works with Redis server 4.0+, with the [Redis Ruby](https://github.com/redis/redis-rb) client version 4.2+.
|
216
|
+
|
205
217
|
### Setting SSL options on Redis Connections
|
206
218
|
|
207
219
|
If you need to connect to Redis with SSL, the recommended approach is to set your Redis instance manually by adding an entry to the `Kredis::Connections.connections` hash. Below an example showing how to connect to Redis using Client Authentication:
|
@@ -231,7 +243,7 @@ The above code could be added to either `config/environments/production.rb` or a
|
|
231
243
|
|
232
244
|
### Configure how the redis client is created
|
233
245
|
|
234
|
-
You can configure how the redis client is created by setting `config.connector` in your `application.rb`:
|
246
|
+
You can configure how the redis client is created by setting `config.kredis.connector` in your `application.rb`:
|
235
247
|
|
236
248
|
```ruby
|
237
249
|
config.kredis.connector = ->(config) { SomeRedisProxy.new(config) }
|
data/lib/kredis/attributes.rb
CHANGED
@@ -62,14 +62,18 @@ module Kredis::Attributes
|
|
62
62
|
kredis_connection_with __method__, name, key, available: available, config: config, after_change: after_change
|
63
63
|
end
|
64
64
|
|
65
|
-
def kredis_counter(name, key: nil, config: :shared, after_change: nil)
|
66
|
-
kredis_connection_with __method__, name, key, config: config, after_change: after_change
|
65
|
+
def kredis_counter(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
66
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
67
67
|
end
|
68
68
|
|
69
69
|
def kredis_hash(name, key: nil, typed: :string, config: :shared, after_change: nil)
|
70
70
|
kredis_connection_with __method__, name, key, typed: typed, config: config, after_change: after_change
|
71
71
|
end
|
72
72
|
|
73
|
+
def kredis_boolean(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
74
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
75
|
+
end
|
76
|
+
|
73
77
|
private
|
74
78
|
def kredis_connection_with(method, name, key, **options)
|
75
79
|
ivar_symbol = :"@#{name}_#{method}"
|
@@ -93,6 +97,7 @@ module Kredis::Attributes
|
|
93
97
|
case key
|
94
98
|
when String then key
|
95
99
|
when Proc then key.call(self)
|
100
|
+
when Symbol then send(key)
|
96
101
|
end
|
97
102
|
end
|
98
103
|
|
data/lib/kredis/migration.rb
CHANGED
@@ -10,29 +10,35 @@ class Kredis::Migration
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def migrate_all(key_pattern)
|
13
|
-
each_key_batch_matching(key_pattern) do |keys|
|
13
|
+
each_key_batch_matching(key_pattern) do |keys, pipeline|
|
14
14
|
keys.each do |key|
|
15
15
|
ids = key.scan(/\d+/).map(&:to_i)
|
16
|
-
migrate from: key, to: yield(key, *ids)
|
16
|
+
migrate from: key, to: yield(key, *ids), pipeline: pipeline
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def migrate(from:, to:)
|
21
|
+
def migrate(from:, to:, pipeline: nil)
|
22
22
|
namespaced_to = Kredis.namespaced_key(to)
|
23
23
|
|
24
24
|
if to.present? && from != namespaced_to
|
25
25
|
log_migration "Migrating key #{from} to #{namespaced_to}" do
|
26
|
-
@redis.evalsha @copy_sha, keys: [ from, namespaced_to ]
|
26
|
+
(pipeline || @redis).evalsha @copy_sha, keys: [ from, namespaced_to ]
|
27
27
|
end
|
28
28
|
else
|
29
29
|
log_migration "Skipping blank/unaltered migration key #{from} → #{to}"
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def delete_all(
|
34
|
-
|
35
|
-
|
33
|
+
def delete_all(*key_patterns)
|
34
|
+
log_migration "DELETE ALL #{key_patterns.inspect}" do
|
35
|
+
if key_patterns.length > 1
|
36
|
+
@redis.del *key_patterns
|
37
|
+
else
|
38
|
+
each_key_batch_matching(key_patterns.first) do |keys, pipeline|
|
39
|
+
pipeline.del *keys
|
40
|
+
end
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
@@ -43,7 +49,7 @@ class Kredis::Migration
|
|
43
49
|
cursor = "0"
|
44
50
|
begin
|
45
51
|
cursor, keys = @redis.scan(cursor, match: key_pattern, count: SCAN_BATCH_SIZE)
|
46
|
-
@redis.
|
52
|
+
@redis.multi { |pipeline| yield keys, pipeline }
|
47
53
|
end until cursor == "0"
|
48
54
|
end
|
49
55
|
|
data/lib/kredis/type/json.rb
CHANGED
@@ -4,14 +4,15 @@ class Kredis::Types::CallbacksProxy
|
|
4
4
|
|
5
5
|
AFTER_CHANGE_OPERATIONS = {
|
6
6
|
Kredis::Types::Counter => %i[ increment decrement reset ],
|
7
|
-
Kredis::Types::Cycle => %i[ next ],
|
7
|
+
Kredis::Types::Cycle => %i[ next reset ],
|
8
8
|
Kredis::Types::Enum => %i[ value= reset ],
|
9
9
|
Kredis::Types::Flag => %i[ mark remove ],
|
10
10
|
Kredis::Types::Hash => %i[ update delete []= remove ],
|
11
11
|
Kredis::Types::List => %i[ remove prepend append << ],
|
12
12
|
Kredis::Types::Scalar => %i[ value= clear ],
|
13
13
|
Kredis::Types::Set => %i[ add << remove replace take clear ],
|
14
|
-
Kredis::Types::Slots => %i[ reserve release reset ]
|
14
|
+
Kredis::Types::Slots => %i[ reserve release reset ],
|
15
|
+
Kredis::Types::UniqueList => %i[ remove prepend append << ]
|
15
16
|
}
|
16
17
|
|
17
18
|
def initialize(type, callback)
|
data/lib/kredis/types/counter.rb
CHANGED
@@ -7,14 +7,14 @@ class Kredis::Types::Counter < Kredis::Types::Proxying
|
|
7
7
|
multi do
|
8
8
|
set 0, ex: expires_in, nx: true
|
9
9
|
incrby by
|
10
|
-
end
|
10
|
+
end[-1]
|
11
11
|
end
|
12
12
|
|
13
13
|
def decrement(by: 1)
|
14
14
|
multi do
|
15
15
|
set 0, ex: expires_in, nx: true
|
16
16
|
decrby by
|
17
|
-
end
|
17
|
+
end[-1]
|
18
18
|
end
|
19
19
|
|
20
20
|
def value
|
data/lib/kredis/types/enum.rb
CHANGED
@@ -28,6 +28,7 @@ class Kredis::Types::Enum < Kredis::Types::Proxying
|
|
28
28
|
def define_predicates_for_values
|
29
29
|
values.each do |defined_value|
|
30
30
|
define_singleton_method("#{defined_value}?") { value == defined_value }
|
31
|
+
define_singleton_method("#{defined_value}!") { self.value = defined_value }
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
data/lib/kredis/types/hash.rb
CHANGED
data/lib/kredis/types/list.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Kredis::Types::List < Kredis::Types::Proxying
|
2
|
-
proxying :lrange, :lrem, :lpush, :rpush, :exists
|
2
|
+
proxying :lrange, :lrem, :lpush, :ltrim, :rpush, :exists?, :del
|
3
3
|
|
4
4
|
attr_accessor :typed
|
5
5
|
|
@@ -20,4 +20,8 @@ class Kredis::Types::List < Kredis::Types::Proxying
|
|
20
20
|
rpush types_to_strings(elements, typed) if elements.flatten.any?
|
21
21
|
end
|
22
22
|
alias << append
|
23
|
+
|
24
|
+
def clear
|
25
|
+
del
|
26
|
+
end
|
23
27
|
end
|
data/lib/kredis/types/proxy.rb
CHANGED
@@ -2,15 +2,22 @@ class Kredis::Types::Proxy
|
|
2
2
|
require_relative "proxy/failsafe"
|
3
3
|
include Failsafe
|
4
4
|
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :key
|
6
|
+
|
7
|
+
thread_mattr_accessor :pipeline
|
6
8
|
|
7
9
|
def initialize(redis, key, **options)
|
8
10
|
@redis, @key = redis, key
|
9
11
|
options.each { |key, value| send("#{key}=", value) }
|
10
12
|
end
|
11
13
|
|
12
|
-
def multi(
|
13
|
-
redis.multi(
|
14
|
+
def multi(*args, **kwargs, &block)
|
15
|
+
redis.multi(*args, **kwargs) do |pipeline|
|
16
|
+
self.pipeline = pipeline
|
17
|
+
block.call
|
18
|
+
ensure
|
19
|
+
self.pipeline = nil
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
23
|
def method_missing(method, *args, **kwargs)
|
@@ -22,6 +29,10 @@ class Kredis::Types::Proxy
|
|
22
29
|
end
|
23
30
|
|
24
31
|
private
|
32
|
+
def redis
|
33
|
+
pipeline || @redis
|
34
|
+
end
|
35
|
+
|
25
36
|
def log_message(method, *args, **kwargs)
|
26
37
|
args = args.flatten.reject(&:blank?).presence
|
27
38
|
kwargs = kwargs.reject { |_k, v| v.blank? }.presence
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require "active_support/core_ext/module/delegation"
|
2
2
|
|
3
3
|
class Kredis::Types::Proxying
|
4
|
-
attr_accessor :proxy, :
|
4
|
+
attr_accessor :proxy, :key
|
5
5
|
|
6
6
|
def self.proxying(*commands)
|
7
7
|
delegate *commands, to: :proxy
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(redis, key, **options)
|
11
|
-
@
|
11
|
+
@key = key
|
12
12
|
@proxy = Kredis::Types::Proxy.new(redis, key)
|
13
13
|
options.each { |key, value| send("#{key}=", value) }
|
14
14
|
end
|
data/lib/kredis/types/slots.rb
CHANGED
@@ -19,10 +19,10 @@ class Kredis::Types::Slots < Kredis::Types::Proxying
|
|
19
19
|
release
|
20
20
|
end
|
21
21
|
else
|
22
|
-
if
|
22
|
+
if available?
|
23
|
+
incr
|
23
24
|
true
|
24
25
|
else
|
25
|
-
release
|
26
26
|
false
|
27
27
|
end
|
28
28
|
end
|
@@ -30,16 +30,25 @@ class Kredis::Types::Slots < Kredis::Types::Proxying
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def release
|
33
|
-
|
33
|
+
if taken > 0
|
34
|
+
decr
|
35
|
+
true
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
34
39
|
end
|
35
40
|
|
36
41
|
def available?
|
37
42
|
failsafe returning: false do
|
38
|
-
|
43
|
+
taken < available
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
42
47
|
def reset
|
43
48
|
del
|
44
49
|
end
|
50
|
+
|
51
|
+
def taken
|
52
|
+
get.to_i
|
53
|
+
end
|
45
54
|
end
|
@@ -5,19 +5,25 @@ class Kredis::Types::UniqueList < Kredis::Types::List
|
|
5
5
|
attr_accessor :typed, :limit
|
6
6
|
|
7
7
|
def prepend(elements)
|
8
|
+
elements = Array(elements).uniq
|
9
|
+
return if elements.empty?
|
10
|
+
|
8
11
|
multi do
|
9
12
|
remove elements
|
10
13
|
super
|
11
14
|
ltrim 0, (limit - 1) if limit
|
12
|
-
end
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
18
|
def append(elements)
|
19
|
+
elements = Array(elements).uniq
|
20
|
+
return if elements.empty?
|
21
|
+
|
16
22
|
multi do
|
17
23
|
remove elements
|
18
24
|
super
|
19
25
|
ltrim -limit, -1 if limit
|
20
|
-
end
|
26
|
+
end
|
21
27
|
end
|
22
28
|
alias << append
|
23
29
|
end
|
data/lib/kredis/version.rb
CHANGED
data/lib/kredis.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.1
|
4
|
+
version: 1.3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-03-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -29,16 +29,22 @@ dependencies:
|
|
29
29
|
name: redis
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '4.2'
|
35
|
+
- - "<"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '6'
|
35
38
|
type: :runtime
|
36
39
|
prerelease: false
|
37
40
|
version_requirements: !ruby/object:Gem::Requirement
|
38
41
|
requirements:
|
39
|
-
- - "
|
42
|
+
- - ">="
|
40
43
|
- !ruby/object:Gem::Version
|
41
44
|
version: '4.2'
|
45
|
+
- - "<"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '6'
|
42
48
|
- !ruby/object:Gem::Dependency
|
43
49
|
name: rails
|
44
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
115
|
- !ruby/object:Gem::Version
|
110
116
|
version: '0'
|
111
117
|
requirements: []
|
112
|
-
rubygems_version: 3.2
|
118
|
+
rubygems_version: 3.4.2
|
113
119
|
signing_key:
|
114
120
|
specification_version: 4
|
115
121
|
summary: Higher-level data structures built on Redis.
|