riak-shim 0.0.9 → 0.0.10
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.
- data/Gemfile +3 -1
- data/README.md +13 -9
- data/lib/riak-shim/persistable.rb +3 -2
- data/lib/riak-shim/store.rb +6 -1
- data/lib/riak-shim/version.rb +1 -1
- data/riak-shim.gemspec +1 -1
- data/spec/persistable_spec.rb +93 -13
- data/spec/spec_helper.rb +1 -0
- data/spec/store_spec.rb +30 -0
- data/spec/support/camelcase.rb +21 -0
- metadata +6 -4
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -35,10 +35,10 @@ Create a config/database.yml containing the details of your Riak setup like so:
|
|
35
35
|
<<: *default
|
36
36
|
bucket_prefix: myapp_test_
|
37
37
|
|
38
|
-
`bucket_prefix will be prefixed to each bucket name, allowing you to point
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
`bucket_prefix` will be prefixed to each bucket name, allowing you to point
|
39
|
+
multiple applications (or multiple copies of the same application) at a
|
40
|
+
single Riak install. During development, this prevents you from stepping on
|
41
|
+
your own toes.
|
42
42
|
|
43
43
|
## Converting a model to use Riak
|
44
44
|
|
@@ -52,22 +52,25 @@ Then, write a #to_hash method which returns a hash representing your object
|
|
52
52
|
|
53
53
|
def to_hash
|
54
54
|
# Return hashified version of your class
|
55
|
+
{ 'foo' => self.foo, 'bar' => self.bar }
|
55
56
|
end
|
56
57
|
|
57
58
|
You'll use Class#from_hash to create an instance from the hash which was
|
58
59
|
pulled from Riak:
|
59
60
|
|
60
61
|
def self.from_hash(data)
|
62
|
+
# Return a fresh instance of your class populated by the hash provided
|
61
63
|
your_obj = new
|
62
64
|
your_obj.foo = data['foo']
|
63
|
-
|
65
|
+
your_obj.bar = data['bar']
|
64
66
|
return your_obj
|
65
67
|
end
|
66
68
|
|
67
|
-
You can now save instances of your class by calling
|
68
|
-
them from Riak by calling
|
69
|
+
You can now save instances of your class by calling `#save` and later retrieve
|
70
|
+
them from Riak by calling `.for_key`:
|
69
71
|
|
70
|
-
|
72
|
+
an_instance.save
|
73
|
+
retrieved_copy = YourClass.for_key(key)
|
71
74
|
|
72
75
|
### Secondary indexes
|
73
76
|
|
@@ -79,6 +82,7 @@ riak-shim will populate a secondary index for that field.
|
|
79
82
|
|
80
83
|
def fields_to_index
|
81
84
|
# Return an Array of hash keys you would like placed into a secondary index.
|
85
|
+
[foo]
|
82
86
|
end
|
83
87
|
|
84
88
|
The `for_index` method retrieves all records whose value for the given index
|
@@ -105,6 +109,6 @@ Return value is an Array of instances of your class matching the query.
|
|
105
109
|
## TODOS
|
106
110
|
|
107
111
|
- Examples directory
|
108
|
-
-
|
112
|
+
- Keep expanding tests
|
109
113
|
- find less horrible way to deal with index names
|
110
114
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Riak
|
2
2
|
module Shim
|
3
3
|
module Persistable
|
4
|
-
attr_writer :store
|
5
4
|
attr_writer :key
|
6
5
|
|
7
6
|
def key
|
@@ -75,7 +74,9 @@ module Riak
|
|
75
74
|
begin
|
76
75
|
raw = bucket.get(key)
|
77
76
|
data = raw.data
|
78
|
-
from_hash(data)
|
77
|
+
result = from_hash(data)
|
78
|
+
result.key = key
|
79
|
+
result
|
79
80
|
rescue Riak::HTTPFailedRequest
|
80
81
|
return nil
|
81
82
|
end
|
data/lib/riak-shim/store.rb
CHANGED
@@ -7,9 +7,14 @@ module Riak
|
|
7
7
|
attr_writer :config_location
|
8
8
|
attr_writer :riak
|
9
9
|
|
10
|
+
class NoSettingsForCurrentEnvError < StandardError; end
|
11
|
+
class RackEnvNotSetError < StandardError; end
|
12
|
+
|
10
13
|
def config
|
11
|
-
env = ENV['RACK_ENV']
|
14
|
+
env = ENV['RACK_ENV'] or raise RackEnvNotSetError.new
|
12
15
|
@config ||= read_config[env]
|
16
|
+
@config or raise NoSettingsForCurrentEnvError.new(
|
17
|
+
"RACK_ENV #{ENV['RACK_ENV']} not specified in #{config_location}.")
|
13
18
|
end
|
14
19
|
|
15
20
|
def read_config
|
data/lib/riak-shim/version.rb
CHANGED
data/riak-shim.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.add_dependency 'riak-client', '~>1.0.4'
|
19
19
|
gem.add_dependency 'excon'
|
20
|
-
gem.add_dependency 'uuidtools', '~>2.1.
|
20
|
+
gem.add_dependency 'uuidtools', '~>2.1.3'
|
21
21
|
|
22
22
|
gem.add_development_dependency "rake"
|
23
23
|
gem.add_development_dependency "rspec"
|
data/spec/persistable_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'riak-shim/persistable'
|
3
|
+
require 'support/camelcase'
|
3
4
|
|
4
5
|
class PersistableExample
|
5
6
|
include Riak::Shim::Persistable
|
@@ -16,12 +17,27 @@ class PersistableExample
|
|
16
17
|
result.baz = data['baz']
|
17
18
|
result
|
18
19
|
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
other.instance_of?(self.class) and
|
23
|
+
self.key == other.key and
|
24
|
+
self.foo == other.foo and
|
25
|
+
self.bar == other.bar and
|
26
|
+
self.baz == other.baz
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class PersistableExampleWithIndex < PersistableExample
|
31
|
+
def fields_to_index
|
32
|
+
[:bar, :baz]
|
33
|
+
end
|
19
34
|
end
|
20
35
|
|
21
36
|
describe 'persistable' do
|
22
37
|
let(:persistable) do
|
23
38
|
p = PersistableExample.new ; p.foo = 'boo' ; p.bar = 'who' ; p
|
24
39
|
end
|
40
|
+
let(:bucket) { PersistableExample.bucket }
|
25
41
|
|
26
42
|
before do
|
27
43
|
Riak::Shim::Store.any_instance.stub(:read_config).and_return(DB_CONFIG)
|
@@ -39,7 +55,7 @@ describe 'persistable' do
|
|
39
55
|
|
40
56
|
describe '#bucket' do
|
41
57
|
it 'returns the correct bucket' do
|
42
|
-
|
58
|
+
bucket.name.should == 'test_persistable_example'
|
43
59
|
end
|
44
60
|
end
|
45
61
|
|
@@ -53,13 +69,13 @@ describe 'persistable' do
|
|
53
69
|
it 'increases key count' do
|
54
70
|
expect do
|
55
71
|
persistable.save
|
56
|
-
end.to change{
|
72
|
+
end.to change{ bucket.keys.count }.by(1)
|
57
73
|
end
|
58
74
|
|
59
75
|
it 'can then be retrieved' do
|
60
76
|
persistable.save
|
61
77
|
retrieved = PersistableExample.for_key(persistable.key)
|
62
|
-
retrieved.
|
78
|
+
retrieved.should eq persistable
|
63
79
|
end
|
64
80
|
end
|
65
81
|
|
@@ -70,7 +86,7 @@ describe 'persistable' do
|
|
70
86
|
end
|
71
87
|
|
72
88
|
it 'removes the key' do
|
73
|
-
|
89
|
+
bucket.exists?(persistable.key).should be_false
|
74
90
|
end
|
75
91
|
end
|
76
92
|
|
@@ -92,12 +108,6 @@ describe 'persistable' do
|
|
92
108
|
end
|
93
109
|
|
94
110
|
context 'with a model which needs indexes' do
|
95
|
-
class PersistableExampleWithIndex < PersistableExample
|
96
|
-
def fields_to_index
|
97
|
-
[:bar, :baz]
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
111
|
let(:indexable) { PersistableExampleWithIndex.new }
|
102
112
|
before do
|
103
113
|
indexable.foo = 1
|
@@ -113,21 +123,91 @@ describe 'persistable' do
|
|
113
123
|
end
|
114
124
|
|
115
125
|
describe '#delete_all' do
|
126
|
+
before do
|
127
|
+
10.times do |i|
|
128
|
+
p = PersistableExample.new
|
129
|
+
p.foo, p.bar, p.baz = i, i, i
|
130
|
+
p.save
|
131
|
+
end
|
132
|
+
@keys = bucket.keys
|
133
|
+
PersistableExample.delete_all
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'has no instances in the DB' do
|
137
|
+
@keys.map { |k| bucket.exists?(k).should be_false }
|
138
|
+
end
|
116
139
|
end
|
117
140
|
|
118
141
|
describe '#de_camel' do
|
142
|
+
it 'handles a bacic camel-case name' do
|
143
|
+
DeCamel.each do |camelcase, lowered|
|
144
|
+
PersistableExample.de_camel(camelcase).should eq(lowered)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'handles runs of capitals appropriately' do
|
149
|
+
DeCamelCapsRuns.each do |camelcase, lowered|
|
150
|
+
PersistableExample.de_camel(camelcase).should eq(lowered)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'turns module separators into slashes' do
|
155
|
+
DeCamelWithModule.each do |camelcase, lowered|
|
156
|
+
PersistableExample.de_camel(camelcase).should eq(lowered)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'does not produce collisions' do
|
161
|
+
PersistableExample.de_camel('RiakShim').should_not
|
162
|
+
eq PersistableExample.de_camel('Riak::Shim')
|
163
|
+
end
|
119
164
|
end
|
120
165
|
|
121
166
|
describe '#for_key' do
|
122
|
-
it 'fetches items for keys which exist'
|
123
|
-
|
167
|
+
it 'fetches items for keys which exist' do
|
168
|
+
persistable.save
|
169
|
+
PersistableExample.for_key(persistable.key).should eq persistable
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'returns null when the key does not exist' do
|
173
|
+
PersistableExample.for_key('no such key').should be_nil
|
174
|
+
end
|
124
175
|
end
|
125
176
|
|
126
177
|
describe '#for_index' do
|
178
|
+
before do
|
179
|
+
@indexed = []
|
180
|
+
3.times do |i|
|
181
|
+
indexable = PersistableExampleWithIndex.new
|
182
|
+
indexable.foo = i
|
183
|
+
indexable.bar = 'wombat'
|
184
|
+
indexable.save
|
185
|
+
@indexed << indexable
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
after do
|
190
|
+
PersistableExampleWithIndex.delete_all
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'returns all items which match indexed value' do
|
194
|
+
PersistableExampleWithIndex.for_index('bar_bin', 'wombat').should =~ @indexed
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'returns an empty list when no matches are found' do
|
198
|
+
PersistableExampleWithIndex.for_index('bar_bin', 'chew').should be_empty
|
199
|
+
end
|
127
200
|
end
|
128
201
|
|
129
202
|
describe '#gen_key' do
|
130
|
-
|
203
|
+
before do
|
204
|
+
@keys = []
|
205
|
+
20.times { @keys << PersistableExample.gen_key }
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'produces no duplicates when called a bunch of times' do
|
209
|
+
@keys.uniq!.should be_nil
|
210
|
+
end
|
131
211
|
end
|
132
212
|
end
|
133
213
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@ $: << './lib'
|
|
2
2
|
require 'riak-shim'
|
3
3
|
require 'pry'
|
4
4
|
|
5
|
+
ENV['RACK_ENV'] = 'test' unless ENV['RACK_ENV']
|
5
6
|
DB_CONFIG = { 'development' => { 'bucket_prefix' => 'dev_', 'host' => "localhost", 'http_port' => 8098},
|
6
7
|
'test' => {'bucket_prefix' => 'test_', 'host' => "localhost", 'http_port' => 8098 }}
|
7
8
|
|
data/spec/store_spec.rb
CHANGED
@@ -25,6 +25,36 @@ describe Riak::Shim::Store do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
describe 'error handling' do
|
29
|
+
before do
|
30
|
+
@stashed_rack_env = ENV['RACK_ENV']
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
ENV['RACK_ENV'] = @stashed_rack_env
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with current RACK_ENV not explicitly configured in database.yml' do
|
38
|
+
before do
|
39
|
+
ENV['RACK_ENV'] = 'production'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises an error" do
|
43
|
+
expect { store.config }.to raise_error(Riak::Shim::Store::NoSettingsForCurrentEnvError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with no RACK_ENV set' do
|
48
|
+
before do
|
49
|
+
ENV['RACK_ENV'] = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it "raises an error" do
|
53
|
+
expect { store.config }.to raise_error(Riak::Shim::Store::RackEnvNotSetError)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
28
58
|
describe '#config' do
|
29
59
|
context 'with RACK_ENV=test' do
|
30
60
|
before do
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
DeCamel = {
|
3
|
+
"Cheezburger" => "cheezburger",
|
4
|
+
"SpecialGuest" => "special_guest",
|
5
|
+
"Area51Controller" => "area51_controller"
|
6
|
+
}
|
7
|
+
|
8
|
+
DeCamelCapsRuns = {
|
9
|
+
"LOLCat" => "lol_cat",
|
10
|
+
"LOLCatBukkit" => "lol_cat_bukkit",
|
11
|
+
"MayberryRFD" => "mayberry_rfd",
|
12
|
+
"CNN" => "cnn",
|
13
|
+
}
|
14
|
+
|
15
|
+
DeCamelWithModule = {
|
16
|
+
"Riak::Shim" => "riak__shim",
|
17
|
+
"Taco::Bell::Dog" => "taco__bell__dog",
|
18
|
+
"PizzaHut::PersonalPanPizza" => "pizza_hut__personal_pan_pizza",
|
19
|
+
}
|
20
|
+
|
21
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riak-shim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07
|
12
|
+
date: 2012-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: riak-client
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 2.1.
|
53
|
+
version: 2.1.3
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.1.
|
61
|
+
version: 2.1.3
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: rake
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,6 +193,7 @@ files:
|
|
193
193
|
- spec/persistable_spec.rb
|
194
194
|
- spec/spec_helper.rb
|
195
195
|
- spec/store_spec.rb
|
196
|
+
- spec/support/camelcase.rb
|
196
197
|
- spec/support/database.yml
|
197
198
|
homepage: https://github.com/mkb/riak-shim
|
198
199
|
licenses: []
|
@@ -223,4 +224,5 @@ test_files:
|
|
223
224
|
- spec/persistable_spec.rb
|
224
225
|
- spec/spec_helper.rb
|
225
226
|
- spec/store_spec.rb
|
227
|
+
- spec/support/camelcase.rb
|
226
228
|
- spec/support/database.yml
|