hikki-redis 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 54541993c901f1077ce9f3f1e679da5e3e6266aa
4
+ data.tar.gz: bb7df13fdb257d939843f56927c864d6009020e4
5
+ SHA512:
6
+ metadata.gz: 322f97c3154c812d9f16c5a09ddc949b4be10b758e49fa172b7841bd63525d7291acec02e96596c40bc90c7607a295a7b8fe2113c021eab805064a0a47aaa929
7
+ data.tar.gz: 31b501644b28b6952ae5318d9199111e296d07ca840b7549f927b031f923195a6d7df992e6be4bd83f66911c69c1ce48b4a4cd90bd074507ea814e76d32a6a1d
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hikki-redis.gemspec
4
+ gemspec
5
+
6
+ # Grab Hikki from local relative
7
+ gem 'hikki', path: '../../'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 alexpeachey
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Hikki::Adapters::RedisAdapter
2
+
3
+ A Redis adapter for Hikki.
4
+ It uses the `redis` gem to communicate with Redis.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'hikki-redis'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install hikki-redis
19
+
20
+ ## Usage
21
+
22
+ By default, the adapter will use `Redis.new` as it's connection which uses the defaults in that gem.
23
+ You can pass in your own connection to use instead, useful for specifying a server and other options.
24
+
25
+ ```ruby
26
+ # Use the default connection
27
+ adapter = Hikki::Adapters::RedisAdapter.new
28
+
29
+ # Use a specific connection
30
+ redis = Redis.new(:url => "redis://:p4ssw0rd@10.0.1.1:6380/15")
31
+ adapter = Hikki::Adapters::RedisAdapter.new(redis)
32
+ ```
33
+
34
+ If you do not specify an `id` when saving, the adapter will generate a uuid using `SecureRandom`.
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it ( http://github.com/originate/hikki/fork )
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Write your specifications
41
+ 4. Implement your specifications
42
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 6. Push to the branch (`git push origin my-new-feature`)
44
+ 7. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ require File.expand_path('../../../lib/hikki/version', __FILE__)
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'hikki-redis'
8
+ spec.version = Hikki::VERSION
9
+ spec.authors = ['alexpeachey']
10
+ spec.email = ['alex.peachey@originate.com']
11
+ spec.summary = 'A Redis adapter for Hikki.'
12
+ spec.description = 'A Redis adapter for Hikki.'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'hikki', Hikki::VERSION
22
+ spec.add_dependency 'redis'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.5'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'rspec'
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'redis'
2
+ require 'hikki'
3
+ require_relative './redis_collection'
4
+
5
+ module Hikki
6
+ module Adapters
7
+ class RedisAdapter < Hikki::Adapters::Adapter
8
+ attr_reader :connection, :uuid_generator
9
+
10
+ def initialize(connection=Redis.new, uuid_generator=SecureRandom)
11
+ super()
12
+ @connection = connection
13
+ @uuid_generator = uuid_generator
14
+ end
15
+
16
+ def collection_for(collection)
17
+ collections.fetch(collection, RedisCollection.new(collection, connection, uuid_generator))
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,105 @@
1
+ module Hikki
2
+ module Adapters
3
+ class RedisCollection < Hikki::Collection
4
+ attr_reader :connection, :uuid_generator
5
+
6
+ def initialize(collection, connection, uuid_generator)
7
+ super(collection)
8
+ @connection = connection
9
+ @uuid_generator = uuid_generator
10
+ end
11
+
12
+ def index(field)
13
+ connection.sadd collection_indexes_key, field.to_s
14
+ true
15
+ end
16
+
17
+ def save(data)
18
+ data = normalize_data(data)
19
+ connection.hset collection_key, data['id'], data.to_json
20
+ add_to_index(data)
21
+ data
22
+ end
23
+
24
+ def find(id)
25
+ JSON.parse(connection.hget(collection_key, id.to_s) || '{}')
26
+ end
27
+
28
+ def all(options={})
29
+ options = normalize_options(options)
30
+ connection.hvals(collection_key)[page_range(options)].map { |j| JSON.parse(j) }
31
+ end
32
+
33
+ def find_by(field, value, options={})
34
+ options = normalize_options(options)
35
+ return find_by_index(field, value, options) if has_index?(field)
36
+ all.select { |o| o.fetch(field.to_s) == value }[page_range(options)]
37
+ end
38
+
39
+ def remove(id)
40
+ remove_from_index(find(id))
41
+ connection.hdel collection_key, id.to_s
42
+ true
43
+ end
44
+
45
+ def remove_all
46
+ indexes.each { |field| connection.del collection_index_key(field) }
47
+ connection.del collection_indexes_key
48
+ connection.del collection_key
49
+ end
50
+
51
+ def has_index?(field)
52
+ connection.sismember collection_indexes_key, field.to_s
53
+ end
54
+
55
+ def indexes
56
+ connection.smembers collection_indexes_key
57
+ end
58
+
59
+ def id_for(data)
60
+ data.fetch('id', uuid_generator.uuid).to_s
61
+ end
62
+
63
+ private
64
+ def collection_indexes_key
65
+ "hikki:#{collection}:indexes"
66
+ end
67
+
68
+ def collection_index_key(field)
69
+ "hikki:#{collection}:#{field.to_s}"
70
+ end
71
+
72
+ def collection_key
73
+ "hikki:#{collection}"
74
+ end
75
+
76
+ def add_to_index(data)
77
+ indexes.each do |field|
78
+ existing = indexed_ids(field, data[field])
79
+ existing << data['id'] unless existing.include? data['id']
80
+ connection.hset collection_index_key(field), data[field], existing.to_json
81
+ end
82
+ end
83
+
84
+ def remove_from_index(data)
85
+ return if data == {}
86
+ indexes.each do |field|
87
+ ids = indexed_ids(field, data[field])
88
+ ids.delete(data['id'])
89
+ connection.hset collection_index_key(field), data[field].to_s, ids.to_json
90
+ end
91
+ end
92
+
93
+ def indexed_ids(field, value)
94
+ JSON.parse(connection.hget(collection_index_key(field), value.to_s) || '[]')
95
+ end
96
+
97
+ def find_by_index(field, value, options)
98
+ ids = indexed_ids(field, value)
99
+ results = connection.pipelined { ids.each { |id| connection.hget collection_key, id } }
100
+ results.map { |j| JSON.parse(j) }.reject { |v| v == {} }[page_range(options)]
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module Hikki
4
+ module Adapters
5
+ describe RedisAdapter, :integration do
6
+ context 'when actually using Redis' do
7
+ subject(:adapter) { RedisAdapter.new }
8
+ let(:data) { { id: id, field1: 'test', field2: 123 } }
9
+ let(:expected) { { 'id' => id, 'field1' => 'test', 'field2' => 123 } }
10
+ let(:id) { '1' }
11
+ let(:collection) { 'collection1' }
12
+
13
+ it 'can store and retreive data' do
14
+ adapter.remove_all(collection)
15
+ adapter.index(collection, :field1)
16
+ adapter.save(collection, data)
17
+ expect(adapter.find(collection, id)).to eq expected
18
+ expect(adapter.find(collection, '2')).to eq Hash.new
19
+ expect(adapter.all(collection)).to eq [expected]
20
+ expect(adapter.find_by(collection, :field1, 'test')).to eq [expected]
21
+ expect(adapter.find_by(collection, :field2, 123)).to eq [expected]
22
+ expect(adapter.find_by(collection, :field1, 'foo')).to eq []
23
+ expect(adapter.find_by(collection, :field2, 1)).to eq []
24
+ adapter.remove(collection, id)
25
+ expect(adapter.find(collection, id)).to eq Hash.new
26
+ expect(adapter.all(collection)).to eq []
27
+ 10.times do |i|
28
+ adapter.save(collection, { id: i, field1: "test-#{i%2}" })
29
+ end
30
+ expect(adapter.all(collection, {limit: 2, offset: 6})).to eq [{'id' => '6', 'field1' => 'test-0'}, {'id' => '7', 'field1' => 'test-1'}]
31
+ expect(adapter.find_by(collection, :field1, 'test-0', {limit: 2})).to eq [{'id' => '0', 'field1' => 'test-0'}, {'id' => '2', 'field1' => 'test-0'}]
32
+ adapter.remove_all(collection)
33
+ expect(adapter.find(collection, id)).to eq Hash.new
34
+ expect(adapter.all(collection)).to eq []
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+
3
+ module Hikki
4
+ module Adapters
5
+ describe RedisAdapter do
6
+ subject(:adapter) { RedisAdapter.new(connection, uuid_generator) }
7
+ let(:connection) { double :connection, sadd: true, smembers: [], hset: true, hget: true, hdel: true, del: true }
8
+ let(:uuid_generator) { double :uuid_generator, uuid: '12345' }
9
+ let(:collection) { 'collection1' }
10
+
11
+ describe '#index' do
12
+ it 'returns true' do
13
+ expect(adapter.index(collection, :field1)).to be_true
14
+ end
15
+
16
+ it 'adds the field to the index list' do
17
+ adapter.index(collection, :field1)
18
+ expect(connection).to have_received(:sadd).with('hikki:collection1:indexes', 'field1')
19
+ end
20
+ end
21
+
22
+ describe '#save' do
23
+ context 'when an id is provided in the data' do
24
+ let(:data) { { id: id, field1: 'test', field2: 123 } }
25
+ let(:expected) { { 'id' => id, 'field1' => 'test', 'field2' => 123 } }
26
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
27
+ let(:id) { '1' }
28
+
29
+ it 'returns the data' do
30
+ expect(adapter.save(collection, data)).to eq expected
31
+ end
32
+
33
+ it 'persists the data in the store' do
34
+ adapter.save(collection, data)
35
+ expect(connection).to have_received(:hset).with('hikki:collection1', id, json)
36
+ end
37
+ end
38
+
39
+ context 'when an id is not provided in the data' do
40
+ let(:data) { { field1: 'test', field2: 123 } }
41
+ let(:expected) { { 'id' => id, 'field1' => 'test', 'field2' => 123 } }
42
+ let(:json) { '{"field1":"test","field2":123,"id":"12345"}' }
43
+ let(:id) { '12345' }
44
+
45
+ it 'returns the data with the id added' do
46
+ expect(adapter.save(collection, data)).to eq expected
47
+ end
48
+
49
+ it 'persists the data in the store' do
50
+ adapter.save(collection, data)
51
+ expect(connection).to have_received(:hset).with('hikki:collection1', id, json)
52
+ end
53
+ end
54
+
55
+ context 'when an index exists on a field in the data' do
56
+ let(:data) { { id: id, field1: 'test', field2: 123 } }
57
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
58
+ let(:id) { '1' }
59
+ before do
60
+ connection.stub(:smembers).with('hikki:collection1:indexes').and_return(['field1'])
61
+ connection.stub(:hget).with('hikki:collection1:field1', 'test').and_return('[]')
62
+ end
63
+
64
+ it 'adds an entry in the index' do
65
+ expect(connection).to receive(:hset).with('hikki:collection1', id, json)
66
+ expect(connection).to receive(:hset).with('hikki:collection1:field1', 'test', '["1"]')
67
+ adapter.save(collection, data)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#find' do
73
+ let(:id) { '1' }
74
+
75
+ context 'when the id exists' do
76
+ let(:data) { { id: id, field1: 'test', field2: 123 } }
77
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
78
+ let(:expected) { { 'id' => id, 'field1' => 'test', 'field2' => 123 } }
79
+ before { connection.stub(:hget).with('hikki:collection1', id).and_return(json) }
80
+
81
+ it 'retrieves the data' do
82
+ expect(adapter.find(collection, id)).to eq expected
83
+ end
84
+ end
85
+
86
+ context 'when the id does not exist' do
87
+ let(:expected) { {} }
88
+ before { connection.stub(:hget).with('hikki:collection1', id).and_return(nil) }
89
+
90
+ it 'returns an empty hash' do
91
+ expect(adapter.find(collection, id)).to eq expected
92
+ end
93
+ end
94
+ end
95
+
96
+ describe '#all' do
97
+ context 'with a record in the collection' do
98
+ let(:data) { { id: '1', field1: 'test', field2: 123 } }
99
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
100
+ let(:expected) { { 'id' => '1', 'field1' => 'test', 'field2' => 123 } }
101
+ before { connection.stub(:hvals).with('hikki:collection1').and_return([json]) }
102
+
103
+ it 'returns an array containing the record' do
104
+ expect(adapter.all(collection)).to eq [expected]
105
+ end
106
+ end
107
+
108
+ context 'with no records in the collection' do
109
+ before { connection.stub(:hvals).with('hikki:collection1').and_return([]) }
110
+
111
+ it 'returns an array containing the record' do
112
+ expect(adapter.all(collection)).to eq []
113
+ end
114
+ end
115
+
116
+ context 'with multiple records and paging options specified' do
117
+ before do
118
+ results = (1..10).map {|i| "{\"id\":\"#{i}\",\"a\":1}" }
119
+ connection.stub(:hvals).with('hikki:collection1').and_return(results)
120
+ end
121
+
122
+ context 'with limit 2' do
123
+ let(:limit) { 2 }
124
+
125
+ it 'returns only 2 records' do
126
+ expect(adapter.all(collection, {limit: 2}).count).to eq 2
127
+ end
128
+
129
+ context 'with an offset of 4' do
130
+ it 'returns the 2 records starting with the offset' do
131
+ expect(adapter.all(collection, {limit: 2, offset: 4})).to eq [{'id' => '5', 'a' => 1}, {'id' => '6', 'a' => 1}]
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '#find_by' do
139
+ context 'with a record in the collection matching' do
140
+ let(:data) { { id: id, field1: 'test', field2: 123 } }
141
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
142
+ let(:expected) { { 'id' => id, 'field1' => 'test', 'field2' => 123 } }
143
+ let(:id) { '1' }
144
+
145
+ context 'without an index' do
146
+ before do
147
+ connection.stub(:sismember).with('hikki:collection1:indexes', 'field2').and_return(false)
148
+ connection.stub(:hvals).with('hikki:collection1').and_return([json])
149
+ end
150
+
151
+ it 'returns an array containing the record' do
152
+ expect(adapter.find_by(collection, :field2, 123)).to eq [expected]
153
+ end
154
+ end
155
+
156
+ context 'with an index' do
157
+ before do
158
+ connection.stub(:sismember).with('hikki:collection1:indexes', 'field1').and_return(true)
159
+ connection.stub(:hget).with('hikki:collection1:field1', 'test').and_return('[1]')
160
+ connection.stub(:hget).with('hikki:collection1', id).and_return(json)
161
+ connection.stub(:pipelined).and_yield.and_return([json])
162
+ end
163
+
164
+ it 'returns an array containing the record' do
165
+ expect(adapter.find_by(collection, :field1, 'test')).to eq [expected]
166
+ end
167
+ end
168
+ end
169
+
170
+ context 'with no matching records in the collection' do
171
+ before do
172
+ connection.stub(:sismember).with('hikki:collection1:indexes', 'field1').and_return(false)
173
+ connection.stub(:hvals).with('hikki:collection1').and_return([])
174
+ end
175
+
176
+ it 'returns an empty array' do
177
+ expect(adapter.find_by(collection, :field1, 'foo')).to eq []
178
+ end
179
+ end
180
+
181
+ context 'with multiple matching records and paging options specified' do
182
+ before do
183
+ results = (1..10).map {|i| "{\"id\":\"#{i}\",\"a\":1}" }
184
+ connection.stub(:sismember).with('hikki:collection1:indexes', 'a').and_return(false)
185
+ connection.stub(:hvals).with('hikki:collection1').and_return(results)
186
+ end
187
+
188
+ context 'with limit 2' do
189
+ let(:limit) { 2 }
190
+
191
+ it 'returns only 2 records' do
192
+ expect(adapter.find_by(collection, :a, 1, {limit: 2}).count).to eq 2
193
+ end
194
+
195
+ context 'with an offset of 4' do
196
+ it 'returns the 2 records starting with the offset' do
197
+ expect(adapter.find_by(collection, :a, 1, {limit: 2, offset: 4})).to eq [{'id' => '5', 'a' => 1}, {'id' => '6', 'a' => 1}]
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ describe '#remove' do
205
+ context 'with a record for the id in the collection' do
206
+ let(:id) { '1' }
207
+ let(:json) { '{"id":"1","field1":"test","field2":123}' }
208
+ before { connection.stub(:hget).with('hikki:collection1', id).and_return(json) }
209
+
210
+ it 'returns true' do
211
+ expect(adapter.remove(collection, id)).to be_true
212
+ end
213
+
214
+ it 'removes the record from the store' do
215
+ adapter.remove(collection, id)
216
+ expect(connection).to have_received(:hdel).with('hikki:collection1', id)
217
+ end
218
+
219
+ context 'when there is an index' do
220
+ before do
221
+ connection.stub(:smembers).with('hikki:collection1:indexes').and_return(['field1'])
222
+ connection.stub(:hget).with('hikki:collection1:field1', 'test').and_return('["1"]')
223
+ end
224
+
225
+ it 'removes the id from the index' do
226
+ adapter.remove(collection, id)
227
+ expect(connection).to have_received(:hset).with('hikki:collection1:field1', 'test', '[]')
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ describe '#remove_all' do
234
+ context 'with a record in the collection' do
235
+ it 'returns true' do
236
+ expect(adapter.remove_all(collection)).to be_true
237
+ end
238
+
239
+ it 'removes all records from the store' do
240
+ expect(connection).to receive(:del).with('hikki:collection1:indexes')
241
+ expect(connection).to receive(:del).with('hikki:collection1')
242
+ adapter.remove_all(collection)
243
+ end
244
+
245
+ context 'when there is an index' do
246
+ before { connection.stub(:smembers).with('hikki:collection1:indexes').and_return(['field1']) }
247
+
248
+ it 'removes the indexes' do
249
+ adapter.remove_all(collection)
250
+ expect(connection).to have_received(:del).with('hikki:collection1:field1')
251
+ expect(connection).to have_received(:del).with('hikki:collection1:indexes')
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'hikki/adapters/redis_adapter'
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+ config.filter_run_excluding :integration
8
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hikki-redis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - alexpeachey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hikki
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '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'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
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: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A Redis adapter for Hikki.
84
+ email:
85
+ - alex.peachey@originate.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .rspec
91
+ - .travis.yml
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - hikki-redis.gemspec
97
+ - lib/hikki/adapters/redis_adapter.rb
98
+ - lib/hikki/adapters/redis_collection.rb
99
+ - spec/hikki/adapters/redis_adapter_integration_spec.rb
100
+ - spec/hikki/adapters/redis_adapter_spec.rb
101
+ - spec/spec_helper.rb
102
+ homepage: ''
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.1
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: A Redis adapter for Hikki.
126
+ test_files:
127
+ - spec/hikki/adapters/redis_adapter_integration_spec.rb
128
+ - spec/hikki/adapters/redis_adapter_spec.rb
129
+ - spec/spec_helper.rb