sideroo 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +30 -5
- data/lib/sideroo.rb +4 -1
- data/lib/sideroo/types/base.rb +110 -25
- data/lib/sideroo/version.rb +1 -1
- data/sideroo.gemspec +2 -1
- metadata +4 -4
- data/lib/sideroo/key_builder.rb +0 -53
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c03495a873770c5d552eb9c0ef4101f747f6e1783372eb9bd66c16c5bb407402
|
|
4
|
+
data.tar.gz: d75ddcb78b2604d202227557dc67fdbe32f5002da340e6c2dbfce31bf19adf12
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a2e61addab0caf170ee6f1ab5e064499565995c855777d1dcf2fe75ea11e40b925bd2ef978aeb2aaa1d7c31ffa9ee3236ac7f881d6cd6200e6655c880230d41a
|
|
7
|
+
data.tar.gz: 58441f5659b2bf72dca1289f538966a933793f7d9b2da0c4f2509a2d06d51324bfcf3a46c06df38d49cd33d46c39b4e36b3abddb25f78d36f476330755078601
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -15,11 +15,16 @@ This gem is aimed to provide
|
|
|
15
15
|
example 'top_stories:us:romance'
|
|
16
16
|
key_regex /^top_stories\:(\w{2})\:([^\:]+)$/ # OPTIONAL - read docs below
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
TopStoriesCache.dimensions # ['country', 'category']
|
|
18
20
|
```
|
|
19
|
-
- an **intuitive** Redis key initialization
|
|
21
|
+
- an **intuitive** Redis key initialization & `attr_accessor`
|
|
20
22
|
```rb
|
|
21
23
|
cache = TopStoriesCache.new(country: 'us', category: 'romance')
|
|
22
24
|
# instead of repeating key = "top_stories:#{country}:#{category}"
|
|
25
|
+
|
|
26
|
+
cache.country # us
|
|
27
|
+
cache.genre # romance
|
|
23
28
|
```
|
|
24
29
|
- **object-oriented** methods for each Redis data type
|
|
25
30
|
```rb
|
|
@@ -566,22 +571,42 @@ cache = UserStoriesCache.new(...)
|
|
|
566
571
|
cache.use_client(instance_redis_client)
|
|
567
572
|
```
|
|
568
573
|
|
|
574
|
+
## 7. Advanced usages
|
|
575
|
+
|
|
576
|
+
### 7.1. Dimension validations
|
|
577
|
+
|
|
578
|
+
To keep this gem thin, we have decided not to add explicit support for dimension validation.
|
|
579
|
+
|
|
580
|
+
However, `Sideroo` collaborates perfectly with `ActiveModel::Validations`. Please incorporate at your own needs.
|
|
581
|
+
|
|
582
|
+
```rb
|
|
583
|
+
class TopStoriesCache < Sideroo::Set
|
|
584
|
+
include ActiveModel::Validations
|
|
585
|
+
|
|
586
|
+
key_pattern 'top_stories:{country}:{category}'
|
|
587
|
+
description 'Cache top stories by ID per country and category'
|
|
588
|
+
example 'top_stories:us:romance'
|
|
589
|
+
|
|
590
|
+
validates :country, length: 2
|
|
591
|
+
validates :category, regex: /^[^:]+$/
|
|
592
|
+
end
|
|
593
|
+
```
|
|
569
594
|
|
|
570
|
-
##
|
|
595
|
+
## 8. Development
|
|
571
596
|
|
|
572
597
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
573
598
|
|
|
574
599
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
575
600
|
|
|
576
|
-
##
|
|
601
|
+
## 9. Contributing
|
|
577
602
|
|
|
578
603
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sideroo. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/sideroo/blob/master/CODE_OF_CONDUCT.md).
|
|
579
604
|
|
|
580
605
|
|
|
581
|
-
##
|
|
606
|
+
## 10. License
|
|
582
607
|
|
|
583
608
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
584
609
|
|
|
585
|
-
##
|
|
610
|
+
## 11. Code of Conduct
|
|
586
611
|
|
|
587
612
|
Everyone interacting in the Sideroo project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/sideroo/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/sideroo.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require "sideroo/version"
|
|
2
2
|
require "sideroo/enumerator"
|
|
3
|
-
require "sideroo/key_builder"
|
|
4
3
|
require "sideroo/types/base"
|
|
5
4
|
require "sideroo/types/bitmap"
|
|
6
5
|
require "sideroo/types/hash"
|
|
@@ -14,6 +13,10 @@ module Sideroo
|
|
|
14
13
|
class Error < StandardError; end
|
|
15
14
|
class MissingKeys < ArgumentError; end
|
|
16
15
|
class UnexpectedKeys < ArgumentError; end
|
|
16
|
+
class InvalidExample < StandardError; end
|
|
17
|
+
class InvalidKeyRegex < StandardError; end
|
|
18
|
+
class OutOfOrderConfig < StandardError; end
|
|
19
|
+
class PatternAlreadyDeclared < StandardError; end
|
|
17
20
|
|
|
18
21
|
class Configuration
|
|
19
22
|
attr_accessor :redis_client
|
data/lib/sideroo/types/base.rb
CHANGED
|
@@ -15,19 +15,29 @@ module Sideroo
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def key_pattern(*args)
|
|
18
|
-
|
|
18
|
+
if args.count > 0
|
|
19
|
+
declare_key_pattern(args.first)
|
|
20
|
+
end
|
|
21
|
+
|
|
19
22
|
@key_pattern
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
def key_regex(*args)
|
|
23
|
-
|
|
26
|
+
if args.count > 0
|
|
27
|
+
custom_key_regex_should_be_defined_before_example!
|
|
28
|
+
@key_regex = args.first
|
|
29
|
+
end
|
|
24
30
|
@key_regex || default_key_regex
|
|
25
31
|
end
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
# Provide example to test against key_pattern and key_regex.
|
|
34
|
+
# Strongly recommended. Please watch out for edge cases.
|
|
28
35
|
#
|
|
29
36
|
def example(*args)
|
|
30
|
-
|
|
37
|
+
if args.count > 0
|
|
38
|
+
@example = args.first
|
|
39
|
+
validate_example_and_regex!
|
|
40
|
+
end
|
|
31
41
|
@example
|
|
32
42
|
end
|
|
33
43
|
|
|
@@ -37,9 +47,12 @@ module Sideroo
|
|
|
37
47
|
end
|
|
38
48
|
|
|
39
49
|
def key_attributes
|
|
40
|
-
|
|
50
|
+
regex = /\{([^\{\}]+)\}/
|
|
51
|
+
key_pattern.scan(regex).map(&:first)
|
|
41
52
|
end
|
|
42
53
|
|
|
54
|
+
alias_method :dimensions, :key_attributes
|
|
55
|
+
|
|
43
56
|
def redis_client(*args)
|
|
44
57
|
@redis_client = args.first if args.count > 0
|
|
45
58
|
@redis_client || Sideroo.redis_client
|
|
@@ -66,11 +79,19 @@ module Sideroo
|
|
|
66
79
|
all.each(&:del)
|
|
67
80
|
end
|
|
68
81
|
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def declare_key_pattern(pattern)
|
|
85
|
+
raise Sideroo::PatternAlreadyDeclared unless key_pattern.nil?
|
|
86
|
+
@key_pattern = pattern
|
|
87
|
+
define_dimensions_as_attr_accessors
|
|
71
88
|
end
|
|
72
89
|
|
|
73
|
-
|
|
90
|
+
def define_dimensions_as_attr_accessors
|
|
91
|
+
dimensions.each do |dimension|
|
|
92
|
+
attr_accessor dimension
|
|
93
|
+
end
|
|
94
|
+
end
|
|
74
95
|
|
|
75
96
|
def define_redis_method(method_name)
|
|
76
97
|
define_method method_name do |*args|
|
|
@@ -91,6 +112,31 @@ module Sideroo
|
|
|
91
112
|
|
|
92
113
|
Regexp.new("^#{regex_str}$")
|
|
93
114
|
end
|
|
115
|
+
|
|
116
|
+
def custom_key_regex_should_be_defined_before_example!
|
|
117
|
+
return if example.nil?
|
|
118
|
+
message = 'Custom key regex should be defined before example'
|
|
119
|
+
raise Sideroo::OutOfOrderConfig, message
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Validate if the provided example matches key regex
|
|
123
|
+
#
|
|
124
|
+
def validate_example_and_regex!
|
|
125
|
+
return if example.nil?
|
|
126
|
+
example_valid = example =~ key_regex
|
|
127
|
+
|
|
128
|
+
unless example_valid
|
|
129
|
+
message = "Example does not match key regex: #{key_regex}"
|
|
130
|
+
raise Sideroo::InvalidExample, message
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
values = example.scan(key_regex).first
|
|
134
|
+
|
|
135
|
+
if values.count != dimensions.count
|
|
136
|
+
message = "Expected #{dimensions.count} dimensions, got #{values.count}"
|
|
137
|
+
raise Sideroo::InvalidKeyRegex, message
|
|
138
|
+
end
|
|
139
|
+
end
|
|
94
140
|
end
|
|
95
141
|
|
|
96
142
|
# Methods applied to all types
|
|
@@ -113,25 +159,40 @@ module Sideroo
|
|
|
113
159
|
unlink
|
|
114
160
|
]
|
|
115
161
|
|
|
116
|
-
attr_reader :key
|
|
117
|
-
|
|
118
162
|
def initialize(arg = {})
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
).build
|
|
131
|
-
else
|
|
132
|
-
message = "Hash or String expected. #{arg.class} given."
|
|
133
|
-
raise ArgumentError, message
|
|
163
|
+
case arg
|
|
164
|
+
when ::String
|
|
165
|
+
raw_key = arg
|
|
166
|
+
key_regex = self.class.key_regex
|
|
167
|
+
|
|
168
|
+
message = "Expected pattern #{key_pattern}, got #{arg}"
|
|
169
|
+
raise(ArgumentError, message) if raw_key !~ key_regex
|
|
170
|
+
|
|
171
|
+
values = raw_key.scan(key_regex).first
|
|
172
|
+
self.class.dimensions.zip(values).each do |dimension, value|
|
|
173
|
+
send("#{dimension}=", value)
|
|
134
174
|
end
|
|
175
|
+
when ::Hash
|
|
176
|
+
attr_map = arg
|
|
177
|
+
attr_map.each do |dimension, value|
|
|
178
|
+
send("#{dimension}=", value)
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
message = "Hash or String expected. #{arg.class} given."
|
|
182
|
+
raise ArgumentError, message
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def key
|
|
187
|
+
k = key_pattern
|
|
188
|
+
|
|
189
|
+
self.class.dimensions.each do |dimension|
|
|
190
|
+
term = "{#{dimension}}"
|
|
191
|
+
value = send(dimension)
|
|
192
|
+
k = k.gsub(term, value.to_s)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
k
|
|
135
196
|
end
|
|
136
197
|
|
|
137
198
|
def redis_client=(client)
|
|
@@ -141,5 +202,29 @@ module Sideroo
|
|
|
141
202
|
def redis_client
|
|
142
203
|
@redis_client || self.class.redis_client
|
|
143
204
|
end
|
|
205
|
+
|
|
206
|
+
private
|
|
207
|
+
|
|
208
|
+
def key_pattern
|
|
209
|
+
self.class.key_pattern
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def validate_attrs!(attr_map)
|
|
213
|
+
provided_attrs = attr_map.keys.map(&:to_s)
|
|
214
|
+
key_attributes = self.class.key_attributes(key_pattern)
|
|
215
|
+
|
|
216
|
+
missing_attrs = key_attributes - provided_attrs
|
|
217
|
+
unexpected_attrs = provided_attrs - key_attributes
|
|
218
|
+
|
|
219
|
+
if missing_attrs.any?
|
|
220
|
+
msg = "Missing attributes: #{missing_attrs.join(', ')}"
|
|
221
|
+
raise MissingKeys, msg
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
if unexpected_attrs.any?
|
|
225
|
+
msg = "Unexpected attributes: #{unexpected_attrs.join(', ')}"
|
|
226
|
+
raise UnexpectedKeys, msg
|
|
227
|
+
end
|
|
228
|
+
end
|
|
144
229
|
end
|
|
145
230
|
end
|
data/lib/sideroo/version.rb
CHANGED
data/sideroo.gemspec
CHANGED
|
@@ -18,7 +18,8 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
|
|
19
19
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
20
20
|
spec.metadata["source_code_uri"] = "https://github.com/ntd251/sideroo"
|
|
21
|
-
spec.metadata["changelog_uri"] = "https://github.com/ntd251/sideroo"
|
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/ntd251/sideroo/releases"
|
|
22
|
+
spec.metadata["documentation_uri"] = "https://www.rubydoc.info/github/ntd251/sideroo"
|
|
22
23
|
|
|
23
24
|
# Specify which files should be added to the gem when it is released.
|
|
24
25
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sideroo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Duong Nguyen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-07-
|
|
11
|
+
date: 2020-07-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: "\n Provide a declarative Redis key definition, intuitive key initialization,
|
|
14
14
|
object-oriented methods for Redis data type, and auditable Redis key management.\n
|
|
@@ -32,7 +32,6 @@ files:
|
|
|
32
32
|
- bin/setup
|
|
33
33
|
- lib/sideroo.rb
|
|
34
34
|
- lib/sideroo/enumerator.rb
|
|
35
|
-
- lib/sideroo/key_builder.rb
|
|
36
35
|
- lib/sideroo/types/base.rb
|
|
37
36
|
- lib/sideroo/types/bitmap.rb
|
|
38
37
|
- lib/sideroo/types/hash.rb
|
|
@@ -50,7 +49,8 @@ metadata:
|
|
|
50
49
|
allowed_push_host: https://rubygems.org/
|
|
51
50
|
homepage_uri: https://github.com/ntd251/sideroo
|
|
52
51
|
source_code_uri: https://github.com/ntd251/sideroo
|
|
53
|
-
changelog_uri: https://github.com/ntd251/sideroo
|
|
52
|
+
changelog_uri: https://github.com/ntd251/sideroo/releases
|
|
53
|
+
documentation_uri: https://www.rubydoc.info/github/ntd251/sideroo
|
|
54
54
|
post_install_message:
|
|
55
55
|
rdoc_options: []
|
|
56
56
|
require_paths:
|
data/lib/sideroo/key_builder.rb
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
module Sideroo
|
|
2
|
-
class KeyBuilder
|
|
3
|
-
attr_reader :attr_map
|
|
4
|
-
attr_reader :key_pattern
|
|
5
|
-
|
|
6
|
-
class << self
|
|
7
|
-
def key_attributes(key_pattern)
|
|
8
|
-
regex = /\{([^\{\}]+)\}/
|
|
9
|
-
key_pattern.scan(regex).map(&:first)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def initialize(attr_map:, key_pattern:)
|
|
14
|
-
@attr_map = attr_map
|
|
15
|
-
@key_pattern = key_pattern
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def build
|
|
19
|
-
validate_attrs!
|
|
20
|
-
populate_key
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def validate_attrs!
|
|
26
|
-
provided_attrs = attr_map.keys.map(&:to_s)
|
|
27
|
-
key_attributes = self.class.key_attributes(key_pattern)
|
|
28
|
-
|
|
29
|
-
missing_attrs = key_attributes - provided_attrs
|
|
30
|
-
unexpected_attrs = provided_attrs - key_attributes
|
|
31
|
-
|
|
32
|
-
if missing_attrs.any?
|
|
33
|
-
msg = "Missing attributes: #{missing_attrs.join(', ')}"
|
|
34
|
-
raise MissingKeys, msg
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if unexpected_attrs.any?
|
|
38
|
-
msg = "Unexpected attributes: #{unexpected_attrs.join(', ')}"
|
|
39
|
-
raise UnexpectedKeys, msg
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def populate_key
|
|
44
|
-
key = key_pattern
|
|
45
|
-
attr_map.each do |attr, value|
|
|
46
|
-
term = "{#{attr}}"
|
|
47
|
-
key = key.gsub(term, value.to_s)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
key
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|