active_kv 0.1.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 +7 -0
- data/README.md +39 -0
- data/lib/active_redis.rb +40 -0
- data/lib/active_redis/attributes.rb +297 -0
- data/lib/active_redis/boolean.rb +4 -0
- data/lib/active_redis/relation.rb +92 -0
- data/lib/active_redis/version.rb +3 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2f673f0b0a6150b3b57d6d983dea905450e2bb4
|
4
|
+
data.tar.gz: 36710d432228d89aa41bfabd972756ff1d5f4abf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0895e2ac0c2ad161c42ab2ae7711a14de238dfcd43f66cbcdba43ee9e5dd59429cee9b798f4d33a2e09125bd8d8a4046e33330b4e5331273b1159ab337f3ce5e
|
7
|
+
data.tar.gz: 8a524df8b4d89067c02e7215ff55c3430b9ff5d16e02c83cac92e14d4a7858a5226d5c2a065479d2a1839f29d66ed1f7a66a090e6e5971b02fae9fde8a47c675
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# ActiveRedis
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/active_redis`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'active_redis'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install active_redis
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
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` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/active_redis/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create a new Pull Request
|
data/lib/active_redis.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "active_model"
|
2
|
+
require "redis"
|
3
|
+
|
4
|
+
require "active_redis/version"
|
5
|
+
require "active_redis/attributes"
|
6
|
+
require "active_redis/relation"
|
7
|
+
require "active_redis/boolean"
|
8
|
+
|
9
|
+
module ActiveRedis
|
10
|
+
|
11
|
+
@redis ||= Redis.new
|
12
|
+
|
13
|
+
attr_reader :redis
|
14
|
+
|
15
|
+
class Base
|
16
|
+
|
17
|
+
include ActiveModel::Validations
|
18
|
+
include ActiveModel::Serialization
|
19
|
+
include ActiveModel::Serializers::JSON
|
20
|
+
include ActiveModel::Serializers::Xml
|
21
|
+
include ActiveRedis::Attributes::InstanceMethods
|
22
|
+
include ActiveRedis::Relation::InstanceMethods
|
23
|
+
extend ActiveRedis::Attributes::ClassMethods
|
24
|
+
extend ActiveRedis::Relation::ClassMethods
|
25
|
+
|
26
|
+
def initialize args={}, settings={reload: false}
|
27
|
+
raise TypeError, 'Hash expected.' unless args.is_a? Hash
|
28
|
+
keys.merge!({id: Integer, updated_at: Time})
|
29
|
+
args = Hash[args.map{|(k,v)| [k.to_sym,v]}]
|
30
|
+
@h = args
|
31
|
+
create_relation_methods
|
32
|
+
create_attribute_methods
|
33
|
+
get_attributes reload: settings[:reload]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
extend self
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
##
|
7
|
+
# Save the current record to redis store.
|
8
|
+
#
|
9
|
+
# @return [true,false]
|
10
|
+
#
|
11
|
+
def save
|
12
|
+
valid? ? (set_attributes(attributes) && true) : false
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Reformat object.
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
#
|
20
|
+
def inspect
|
21
|
+
a = keys.reject{|k,v| k == :id }.map do |attribute,type|
|
22
|
+
%Q{#{attribute}=#{send(attribute).inspect}}
|
23
|
+
end
|
24
|
+
%Q{#<#{self.class.name} id=#{self.id} #{a.join(' ')}>}
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Remove the instance from redis store.
|
29
|
+
# Remove all relations to another objects.
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
def remove
|
34
|
+
blto = self.class.instance_variable_get(:@belongs_to)
|
35
|
+
(blto || []).each do |rel|
|
36
|
+
handle_relation relation_key: "#{rel.to_s.singularize}_id",
|
37
|
+
action: :del
|
38
|
+
end
|
39
|
+
connection.del *attribute_paths
|
40
|
+
end
|
41
|
+
|
42
|
+
alias :delete :remove
|
43
|
+
alias :destroy :remove
|
44
|
+
|
45
|
+
##
|
46
|
+
# Get the current attributes.
|
47
|
+
#
|
48
|
+
# @return [Hash]
|
49
|
+
#
|
50
|
+
def attributes
|
51
|
+
get_attributes
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @see ActiveRedis#keys
|
56
|
+
#
|
57
|
+
def keys
|
58
|
+
self.class.keys
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# @see ActiveRedis#connection
|
63
|
+
#
|
64
|
+
def connection
|
65
|
+
self.class.connection
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Implement ActiveModel validation support.
|
70
|
+
#
|
71
|
+
def read_attribute_for_validation key
|
72
|
+
attributes[key]
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
module_function
|
77
|
+
|
78
|
+
##
|
79
|
+
# Create getter/setter/bool methods by attributes.
|
80
|
+
# This method should be called in a constructor.
|
81
|
+
#
|
82
|
+
# @return [void]
|
83
|
+
#
|
84
|
+
def create_attribute_methods
|
85
|
+
self.class.instance_eval do
|
86
|
+
keys.each do |attribute,type|
|
87
|
+
define_method(attribute) do
|
88
|
+
attributes[attribute]
|
89
|
+
end
|
90
|
+
|
91
|
+
define_method("#{attribute}=") do |arg|
|
92
|
+
attributes[attribute] = format_attribute(attribute,arg.to_s)
|
93
|
+
end
|
94
|
+
|
95
|
+
define_method("#{attribute}?") do
|
96
|
+
!attributes[attribute].to_s.empty?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Get attributes from redis store.
|
104
|
+
#
|
105
|
+
# @param reload [true,false] Force reload from redis.
|
106
|
+
#
|
107
|
+
# @return [Hash]
|
108
|
+
#
|
109
|
+
def get_attributes reload: false
|
110
|
+
if reload or not @h
|
111
|
+
h = (@h and @h[:id]) ? connection.hgetall(basename) : {}
|
112
|
+
attribute_hash = {}
|
113
|
+
unless h.empty?
|
114
|
+
keys.each do |k,v|
|
115
|
+
attribute_hash[k.to_sym] = format_attribute(k.to_sym, h[k.to_s])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
@h = attribute_hash
|
119
|
+
end
|
120
|
+
@h
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Casting objects into original values.
|
125
|
+
# The type whould be defined at class method "keys"
|
126
|
+
#
|
127
|
+
# @see ActiveRedis.keys
|
128
|
+
#
|
129
|
+
# @param key [String,Symbol]
|
130
|
+
# @param value [Object]
|
131
|
+
#
|
132
|
+
# @return [Object] Casted value.
|
133
|
+
#
|
134
|
+
def format_attribute key, value
|
135
|
+
case keys[key.to_sym].to_s
|
136
|
+
when /Integer/
|
137
|
+
value.to_i
|
138
|
+
when /Array/
|
139
|
+
connection.lrange("#{basename}:#{key}",0,-1)
|
140
|
+
when /Hash/
|
141
|
+
connection.hgetall("#{basename}:#{key}")
|
142
|
+
when /Time/
|
143
|
+
Time.parse(value) rescue nil
|
144
|
+
else value
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Save given hash to redis server.
|
150
|
+
# Refresh updated_at timestamp.
|
151
|
+
# Unless id isn't set, get the next primary key.
|
152
|
+
#
|
153
|
+
# @param arg [Hash]
|
154
|
+
#
|
155
|
+
# @return [void]
|
156
|
+
#
|
157
|
+
def set_attributes arg
|
158
|
+
remove
|
159
|
+
arg[:updated_at] = Time.now.to_s
|
160
|
+
arg[:id] ||= connection.incr("#{self.class.name}_id")
|
161
|
+
arg.each do |k,v|
|
162
|
+
case v
|
163
|
+
when Array
|
164
|
+
v.each do |v|
|
165
|
+
connection.lpush "#{basename}:#{k}", v
|
166
|
+
end
|
167
|
+
when Hash
|
168
|
+
connection.mapped_hmset "#{basename}:#{k}", v
|
169
|
+
else
|
170
|
+
handle_relation relation_key: k, value: v, action: :add
|
171
|
+
connection.hset basename, k, v
|
172
|
+
end
|
173
|
+
end
|
174
|
+
get_attributes(reload: true)
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Redis basename.
|
179
|
+
#
|
180
|
+
# @return [String]
|
181
|
+
#
|
182
|
+
def basename
|
183
|
+
"#{self.class.name.downcase.pluralize}:#{self.id}"
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Get attribute paths by keys.
|
188
|
+
# Complex types needs to be stored at another path.
|
189
|
+
#
|
190
|
+
# @return [Array]
|
191
|
+
#
|
192
|
+
def attribute_paths
|
193
|
+
keys.map do |k,v|
|
194
|
+
case v.to_s
|
195
|
+
when /Hash/, /Array/ then "#{basename}:#{k}"
|
196
|
+
else basename
|
197
|
+
end
|
198
|
+
end.uniq
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
module ClassMethods
|
204
|
+
|
205
|
+
##
|
206
|
+
# Fromatted class name.
|
207
|
+
#
|
208
|
+
# @return [String]
|
209
|
+
#
|
210
|
+
def cname
|
211
|
+
self.name.downcase.pluralize
|
212
|
+
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# Create a new instance and save it to redis store.
|
216
|
+
#
|
217
|
+
# @return [ActiveRedis::Base]
|
218
|
+
#
|
219
|
+
def create attributes
|
220
|
+
a = self.new(attributes)
|
221
|
+
a.save
|
222
|
+
a
|
223
|
+
end
|
224
|
+
|
225
|
+
##
|
226
|
+
# Get all objects.
|
227
|
+
#
|
228
|
+
# @return [Array<ActiveRedis>]
|
229
|
+
#
|
230
|
+
def all
|
231
|
+
connection.keys("#{cname}:*").map do |key|
|
232
|
+
self.new({id: key[/#{cname}:(\d+)/,1].to_i},reload: true)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Redis base connection.
|
238
|
+
#
|
239
|
+
# @return [Redis]
|
240
|
+
#
|
241
|
+
def connection
|
242
|
+
ActiveRedis.redis
|
243
|
+
end
|
244
|
+
|
245
|
+
##
|
246
|
+
# @param id [Integer]
|
247
|
+
#
|
248
|
+
# @return [ActiveRedis::Base]
|
249
|
+
#
|
250
|
+
def find id
|
251
|
+
a = connection.hgetall("#{cname}:#{id}")
|
252
|
+
self.new({id: id},reload: true) unless a.empty?
|
253
|
+
end
|
254
|
+
|
255
|
+
##
|
256
|
+
# @see where
|
257
|
+
#
|
258
|
+
# @return [ActiveRedis::Base]
|
259
|
+
#
|
260
|
+
def find_by basename: nil
|
261
|
+
if basename
|
262
|
+
where(basename: basename).first
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# @params basename [String]
|
268
|
+
#
|
269
|
+
# @return [Array]
|
270
|
+
#
|
271
|
+
def where basename: nil
|
272
|
+
if basename
|
273
|
+
a = connection.smembers(basename)
|
274
|
+
a.map{ |entry| self.find(entry) }
|
275
|
+
else
|
276
|
+
[]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
##
|
281
|
+
# Set the keys/attributs for an ActiveRedis::Base child.
|
282
|
+
#
|
283
|
+
# Example:
|
284
|
+
#
|
285
|
+
# keys title: String,
|
286
|
+
# number: Integer
|
287
|
+
#
|
288
|
+
def keys hash=nil
|
289
|
+
hash ? (@keys ||= hash) : @keys
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
extend self
|
294
|
+
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Relation
|
3
|
+
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
##
|
9
|
+
# Generate methods for relations.
|
10
|
+
#
|
11
|
+
# @return [void]
|
12
|
+
#
|
13
|
+
def create_relation_methods
|
14
|
+
self.class.instance_eval do
|
15
|
+
(@has_many || []).each do |x|
|
16
|
+
define_method(x.to_s.pluralize) do
|
17
|
+
klazz = Object.const_get(x.to_s.capitalize.singularize)
|
18
|
+
klazz.where(
|
19
|
+
basename: "#{basename}:#{x.to_s.downcase.pluralize}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
(@belongs_to || []).each do |x|
|
23
|
+
keys.merge!({"#{x.to_s.downcase.singularize}_id".to_sym => Integer})
|
24
|
+
define_method(x.to_s.singularize) do
|
25
|
+
klazz = Object.const_get(x.to_s.capitalize.singularize)
|
26
|
+
klazz.find send("#{x.to_s.downcase.singularize}_id")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
(@has_one || []).each do |x|
|
30
|
+
define_method(x.to_s) do
|
31
|
+
klazz = Object.const_get(x.to_s.capitalize.singularize)
|
32
|
+
klazz.find_by(basename: "#{basename}:"+
|
33
|
+
"#{x.to_s.downcase.singularize}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Create a set for each relation. This is needed to
|
41
|
+
# fetch directly the objects by id from redis store.
|
42
|
+
# Nobody wan't to do it only at application level.
|
43
|
+
#
|
44
|
+
# @param relation_key [String] Like Author - Post.author_id
|
45
|
+
# @param value [String]
|
46
|
+
# @param action [:add,:del]
|
47
|
+
#
|
48
|
+
# @return [void]
|
49
|
+
#
|
50
|
+
def handle_relation relation_key: nil, value: nil, action: :add
|
51
|
+
blto = self.class.instance_variable_get(:@belongs_to)
|
52
|
+
relation = relation_key.to_s[/^([a-z_]+)_id$/,1].to_s
|
53
|
+
if blto.is_a?(Array) and
|
54
|
+
blto.include?(relation.to_sym)
|
55
|
+
if action == :add
|
56
|
+
connection.sadd(
|
57
|
+
"#{relation.pluralize}:#{value}:#{self.class.cname}",
|
58
|
+
id)
|
59
|
+
elsif action == :del
|
60
|
+
connection.srem(
|
61
|
+
"#{relation.pluralize}:"+
|
62
|
+
"#{value || send(relation_key)}:"+
|
63
|
+
"#{self.class.cname}",
|
64
|
+
id)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
|
74
|
+
##
|
75
|
+
# Create class level methods.
|
76
|
+
#
|
77
|
+
%w{has_many has_one belongs_to}.each do |m|
|
78
|
+
define_method(m) do |symbol|
|
79
|
+
unless instance_variable_get("@#{m}").is_a?(Array)
|
80
|
+
instance_variable_set("@#{m}",[])
|
81
|
+
end
|
82
|
+
instance_variable_get("@#{m}") << symbol
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
extend self
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_kv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Foerster
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.7.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.7.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: redis
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: active_model
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- timhormersdorf@googlemail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- README.md
|
91
|
+
- lib/active_redis.rb
|
92
|
+
- lib/active_redis/attributes.rb
|
93
|
+
- lib/active_redis/boolean.rb
|
94
|
+
- lib/active_redis/relation.rb
|
95
|
+
- lib/active_redis/version.rb
|
96
|
+
homepage:
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.2.1
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: Get redis relational
|
120
|
+
test_files: []
|