riak-shim 0.0.5 → 0.0.9
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/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/Gemfile +4 -2
- data/README.md +27 -18
- data/Rakefile +20 -0
- data/lib/riak-shim/persistable.rb +11 -5
- data/lib/riak-shim/version.rb +1 -1
- data/riak-shim.gemspec +4 -2
- data/spec/persistable_spec.rb +104 -4
- data/spec/spec_helper.rb +3 -0
- metadata +38 -6
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Riak
|
1
|
+
# Riak Shim
|
2
2
|
|
3
3
|
A teeny shim between your code and the riak-client gem. Reads database configuration
|
4
4
|
out of config/database.yml and derives bucket names from your class names and an
|
@@ -6,8 +6,7 @@ appropriate prefix.
|
|
6
6
|
|
7
7
|
Riak is a database from the good people at Basho. Check it out: http://basho.com/products/riak-overview/
|
8
8
|
|
9
|
-
[](http://travis-ci.org/mkb/riak-shim)
|
10
|
-
|
9
|
+
[](http://travis-ci.org/mkb/riak-shim) [](https://gemnasium.com/mkb/riak-shim) [](https://codeclimate.com/github/mkb/riak-shim)
|
11
10
|
|
12
11
|
## Installation
|
13
12
|
|
@@ -25,16 +24,21 @@ Or install it yourself as:
|
|
25
24
|
|
26
25
|
## Usage
|
27
26
|
|
28
|
-
Create a config/database.yml containing the details of your Riak like so:
|
27
|
+
Create a config/database.yml containing the details of your Riak setup like so:
|
29
28
|
|
30
29
|
development: &default
|
31
|
-
bucket_prefix:
|
30
|
+
bucket_prefix: myapp_dev_
|
32
31
|
host: localhost
|
33
32
|
http_port: 8098
|
34
33
|
|
35
34
|
test:
|
36
35
|
<<: *default
|
37
|
-
bucket_prefix:
|
36
|
+
bucket_prefix: myapp_test_
|
37
|
+
|
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.
|
38
42
|
|
39
43
|
## Converting a model to use Riak
|
40
44
|
|
@@ -43,14 +47,15 @@ In any class you wish to persist, you must include the module:
|
|
43
47
|
require 'riak-shim'
|
44
48
|
include Riak::Shim::Persistable
|
45
49
|
|
46
|
-
Then, write a #to_hash method which returns a hash representing your object
|
47
|
-
going to store):
|
50
|
+
Then, write a #to_hash method which returns a hash representing your object
|
51
|
+
(and consequently, what you are going to store):
|
48
52
|
|
49
53
|
def to_hash
|
50
54
|
# Return hashified version of your class
|
51
55
|
end
|
52
56
|
|
53
|
-
You'll use Class#from_hash to create an instance from the hash which was
|
57
|
+
You'll use Class#from_hash to create an instance from the hash which was
|
58
|
+
pulled from Riak:
|
54
59
|
|
55
60
|
def self.from_hash(data)
|
56
61
|
your_obj = new
|
@@ -59,28 +64,30 @@ You'll use Class#from_hash to create an instance from the hash which was pulled
|
|
59
64
|
return your_obj
|
60
65
|
end
|
61
66
|
|
62
|
-
You can now save instances of
|
63
|
-
by calling...
|
67
|
+
You can now save instances of your class by calling #save and later retrieve
|
68
|
+
them from Riak by calling...
|
64
69
|
|
65
70
|
YourClass.for_key(key)
|
66
71
|
|
67
72
|
### Secondary indexes
|
68
73
|
|
69
|
-
Secondary indexes in Riak allow you to query based on the contents of a
|
70
|
-
|
71
|
-
|
74
|
+
Secondary indexes in Riak allow you to query based on the contents of a
|
75
|
+
particular field. If you'd like to look up your data by the contents
|
76
|
+
of fields, define `#fields_to_index` and return the names of
|
77
|
+
any fields you wish to query on. When you #save an instance of YourClass,
|
78
|
+
riak-shim will populate a secondary index for that field.
|
72
79
|
|
73
80
|
def fields_to_index
|
74
81
|
# Return an Array of hash keys you would like placed into a secondary index.
|
75
|
-
# Return an empty Array if you don't know what this means. :)
|
76
82
|
end
|
77
83
|
|
78
|
-
|
79
|
-
|
84
|
+
The `for_index` method retrieves all records whose value for the given index
|
85
|
+
matches:
|
80
86
|
|
81
87
|
YourClass.for_index(index_name, value)
|
82
88
|
|
83
|
-
|
89
|
+
...where `index_name` is what you defined in `fields_to_index` plus the suffix
|
90
|
+
"_bin" .
|
84
91
|
|
85
92
|
The `value` is what you want to look up.
|
86
93
|
|
@@ -99,3 +106,5 @@ Return value is an Array of instances of your class matching the query.
|
|
99
106
|
|
100
107
|
- Examples directory
|
101
108
|
- Revisit tests
|
109
|
+
- find less horrible way to deal with index names
|
110
|
+
|
data/Rakefile
CHANGED
@@ -1,2 +1,22 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
require "bundler/gem_tasks"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc "Run all specs"
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
10
|
+
spec.rspec_opts = ['--backtrace -cfs']
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Travis build checks for JRuby and adds a needed gem before testing"
|
14
|
+
task :travis => [:check_jruby, :spec]
|
15
|
+
|
16
|
+
desc "JRuby needs an additional gem"
|
17
|
+
task :check_jruby do
|
18
|
+
if RUBY_PLATFORM == 'java'
|
19
|
+
`gem install jruby-openssl`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -2,7 +2,7 @@ module Riak
|
|
2
2
|
module Shim
|
3
3
|
module Persistable
|
4
4
|
attr_writer :store
|
5
|
-
|
5
|
+
attr_writer :key
|
6
6
|
|
7
7
|
def key
|
8
8
|
@key ||= self.class.gen_key
|
@@ -28,12 +28,18 @@ module Riak
|
|
28
28
|
self
|
29
29
|
end
|
30
30
|
|
31
|
+
def destroy
|
32
|
+
bucket.delete(key)
|
33
|
+
end
|
34
|
+
|
31
35
|
def set_indexes(indexes)
|
32
36
|
indexes.clear
|
33
|
-
fields_to_index
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
if self.respond_to?(:fields_to_index)
|
38
|
+
fields_to_index.each do |field|
|
39
|
+
index_name = "#{field}_bin"
|
40
|
+
index_value = send(field)
|
41
|
+
indexes[index_name] << index_value
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
data/lib/riak-shim/version.rb
CHANGED
data/riak-shim.gemspec
CHANGED
@@ -15,13 +15,15 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Riak::Shim::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'riak-client'
|
19
|
-
gem.add_dependency '
|
18
|
+
gem.add_dependency 'riak-client', '~>1.0.4'
|
19
|
+
gem.add_dependency 'excon'
|
20
|
+
gem.add_dependency 'uuidtools', '~>2.1.2'
|
20
21
|
|
21
22
|
gem.add_development_dependency "rake"
|
22
23
|
gem.add_development_dependency "rspec"
|
23
24
|
gem.add_development_dependency "guard"
|
24
25
|
gem.add_development_dependency "guard-rspec"
|
26
|
+
gem.add_development_dependency "pry"
|
25
27
|
|
26
28
|
if RUBY_PLATFORM.include? 'darwin'
|
27
29
|
gem.add_development_dependency 'growl'
|
data/spec/persistable_spec.rb
CHANGED
@@ -1,26 +1,45 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'riak-shim/persistable'
|
3
3
|
|
4
|
-
class
|
4
|
+
class PersistableExample
|
5
5
|
include Riak::Shim::Persistable
|
6
|
+
attr_accessor :foo, :bar, :baz
|
7
|
+
|
8
|
+
def to_hash
|
9
|
+
{ 'foo' => foo, 'bar' => bar, 'baz' => baz }
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_hash(data)
|
13
|
+
result = self.new
|
14
|
+
result.foo = data['foo']
|
15
|
+
result.bar = data['bar']
|
16
|
+
result.baz = data['baz']
|
17
|
+
result
|
18
|
+
end
|
6
19
|
end
|
7
20
|
|
8
21
|
describe 'persistable' do
|
9
|
-
let(:persistable)
|
22
|
+
let(:persistable) do
|
23
|
+
p = PersistableExample.new ; p.foo = 'boo' ; p.bar = 'who' ; p
|
24
|
+
end
|
10
25
|
|
11
26
|
before do
|
12
27
|
Riak::Shim::Store.any_instance.stub(:read_config).and_return(DB_CONFIG)
|
13
28
|
end
|
14
29
|
|
30
|
+
after do
|
31
|
+
PersistableExample.delete_all
|
32
|
+
end
|
33
|
+
|
15
34
|
describe '#bucket_name' do
|
16
35
|
it 'composes #db_name and class name' do
|
17
|
-
persistable.bucket_name.should == '
|
36
|
+
persistable.bucket_name.should == 'test_persistable_example'
|
18
37
|
end
|
19
38
|
end
|
20
39
|
|
21
40
|
describe '#bucket' do
|
22
41
|
it 'returns the correct bucket' do
|
23
|
-
persistable.bucket.name.should == '
|
42
|
+
persistable.bucket.name.should == 'test_persistable_example'
|
24
43
|
end
|
25
44
|
end
|
26
45
|
|
@@ -29,5 +48,86 @@ describe 'persistable' do
|
|
29
48
|
persistable.store.should respond_to(:bucket)
|
30
49
|
end
|
31
50
|
end
|
51
|
+
|
52
|
+
describe '#save' do
|
53
|
+
it 'increases key count' do
|
54
|
+
expect do
|
55
|
+
persistable.save
|
56
|
+
end.to change{ persistable.bucket.keys.count }.by(1)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'can then be retrieved' do
|
60
|
+
persistable.save
|
61
|
+
retrieved = PersistableExample.for_key(persistable.key)
|
62
|
+
retrieved.should_not be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#destroy' do
|
67
|
+
before do
|
68
|
+
persistable.save
|
69
|
+
persistable.destroy
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'removes the key' do
|
73
|
+
persistable.bucket.exists?(persistable.key).should be_false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#set_indexes' do
|
78
|
+
before do
|
79
|
+
@indexes = Hash.new { |hash, key| hash[key] = [] }
|
80
|
+
@indexes[:oldkey] = ['oldval']
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'with a model which does not need indes' do
|
84
|
+
it 'does not require #fields_to_index to be defined' do
|
85
|
+
expect { persistable.set_indexes(@indexes) }.to_not raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'clears preexisting indexes' do
|
89
|
+
persistable.set_indexes(@indexes)
|
90
|
+
@indexes.should be_empty
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
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
|
+
let(:indexable) { PersistableExampleWithIndex.new }
|
102
|
+
before do
|
103
|
+
indexable.foo = 1
|
104
|
+
indexable.bar = 2
|
105
|
+
indexable.baz = 3
|
106
|
+
indexable.set_indexes(@indexes)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'sets indexes for specified fields and no others' do
|
110
|
+
@indexes.keys.should =~ ['bar_bin', 'baz_bin']
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#delete_all' do
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#de_camel' do
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#for_key' do
|
122
|
+
it 'fetches items for keys which exist'
|
123
|
+
it 'returns null when the key does not exist'
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#for_index' do
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#gen_key' do
|
130
|
+
it 'produces no duplicates when called a bunch of times'
|
131
|
+
end
|
32
132
|
end
|
33
133
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
$: << './lib'
|
2
2
|
require 'riak-shim'
|
3
|
+
require 'pry'
|
3
4
|
|
4
5
|
DB_CONFIG = { 'development' => { 'bucket_prefix' => 'dev_', 'host' => "localhost", 'http_port' => 8098},
|
5
6
|
'test' => {'bucket_prefix' => 'test_', 'host' => "localhost", 'http_port' => 8098 }}
|
7
|
+
|
8
|
+
Riak.disable_list_keys_warnings = true
|
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.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,26 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: riak-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: excon
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
@@ -32,17 +48,17 @@ dependencies:
|
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
33
49
|
none: false
|
34
50
|
requirements:
|
35
|
-
- -
|
51
|
+
- - ~>
|
36
52
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
53
|
+
version: 2.1.2
|
38
54
|
type: :runtime
|
39
55
|
prerelease: false
|
40
56
|
version_requirements: !ruby/object:Gem::Requirement
|
41
57
|
none: false
|
42
58
|
requirements:
|
43
|
-
- -
|
59
|
+
- - ~>
|
44
60
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
61
|
+
version: 2.1.2
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: rake
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +123,22 @@ dependencies:
|
|
107
123
|
- - ! '>='
|
108
124
|
- !ruby/object:Gem::Version
|
109
125
|
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pry
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
110
142
|
- !ruby/object:Gem::Dependency
|
111
143
|
name: growl
|
112
144
|
requirement: !ruby/object:Gem::Requirement
|