riak-client 1.1.1 → 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.
- data/Gemfile +2 -2
- data/RELEASE_NOTES.md +22 -0
- data/lib/riak/bucket.rb +10 -1
- data/lib/riak/client.rb +7 -0
- data/lib/riak/client/beefcake_protobuffs_backend.rb +7 -1
- data/lib/riak/client/excon_backend.rb +15 -5
- data/lib/riak/client/feature_detection.rb +8 -1
- data/lib/riak/client/http_backend.rb +16 -0
- data/lib/riak/map_reduce/phase.rb +2 -2
- data/lib/riak/version.rb +1 -1
- data/lib/riak/walk_spec.rb +1 -0
- data/riak-client.gemspec +1 -1
- data/spec/integration/riak/http_backends_spec.rb +15 -0
- data/spec/integration/riak/protobuffs_backends_spec.rb +14 -0
- data/spec/riak/bucket_spec.rb +8 -0
- data/spec/riak/feature_detection_spec.rb +17 -1
- data/spec/riak/map_reduce/phase_spec.rb +11 -5
- data/spec/riak/walk_spec_spec.rb +4 -0
- metadata +10 -4
data/Gemfile
CHANGED
data/RELEASE_NOTES.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# Riak Ruby Client Release Notes
|
2
2
|
|
3
|
+
## 1.2.0 Feature Release - 2013-05-15
|
4
|
+
|
5
|
+
Release 1.2.0 adds support for Riak 1.3 and fixes a number of bugs.
|
6
|
+
|
7
|
+
Features:
|
8
|
+
|
9
|
+
* The "clear bucket properties" feature has been added. This resets
|
10
|
+
modified bucket properties to the defaults on Riak 1.3+ clusters.
|
11
|
+
* Anonymous "strfun" MapReduce functions written in Erlang can now be
|
12
|
+
sent from the client, if they are enabled on the server-side.
|
13
|
+
|
14
|
+
Bugfixes:
|
15
|
+
|
16
|
+
* The WalkSpec class now properly includes the Translation module.
|
17
|
+
* The Protocol Buffers transport now extracts the bucket name before
|
18
|
+
submitting secondary index queries.
|
19
|
+
* Search query results returned over PBC are assumed to be UTF-8
|
20
|
+
encoded.
|
21
|
+
* The newer Excon API is now supported (>= 0.19.0).
|
22
|
+
* When enabling the search commit hook, the 'precommit' property will
|
23
|
+
now be checked more safely.
|
24
|
+
|
3
25
|
## 1.1.1 Patch/Bugfix Release - 2013-01-10
|
4
26
|
|
5
27
|
Release 1.1.1 fixes a minor bug with Net::HTTP on Ruby 1.8.7 with
|
data/lib/riak/bucket.rb
CHANGED
@@ -78,6 +78,15 @@ module Riak
|
|
78
78
|
end
|
79
79
|
alias :properties :props
|
80
80
|
|
81
|
+
# Clears bucket properties, reverting them to the defaults.
|
82
|
+
# @return [true, false] whether the properties were cleared
|
83
|
+
# @since Riak 1.3
|
84
|
+
def clear_props
|
85
|
+
@props = nil
|
86
|
+
@client.clear_bucket_props(self)
|
87
|
+
end
|
88
|
+
alias :clear_properties :clear_props
|
89
|
+
|
81
90
|
# Retrieve an object from within the bucket.
|
82
91
|
# @param [String] key the key of the object to retrieve
|
83
92
|
# @param [Hash] options query parameters for the request
|
@@ -205,7 +214,7 @@ module Riak
|
|
205
214
|
# riak_search.
|
206
215
|
# @return [true,false] whether the bucket includes the search indexing hook
|
207
216
|
def is_indexed?
|
208
|
-
props['search'] == true || props['precommit'].include?(SEARCH_PRECOMMIT_HOOK)
|
217
|
+
props['search'] == true || (props.has_key?('precommit') && props['precommit'].include?(SEARCH_PRECOMMIT_HOOK))
|
209
218
|
end
|
210
219
|
|
211
220
|
# @return [String] a representation suitable for IRB and debugging output
|
data/lib/riak/client.rb
CHANGED
@@ -469,6 +469,13 @@ module Riak
|
|
469
469
|
end
|
470
470
|
end
|
471
471
|
|
472
|
+
# Clears the properties on a bucket. See Bucket#clear_props
|
473
|
+
def clear_bucket_props(bucket)
|
474
|
+
http do |b|
|
475
|
+
b.clear_bucket_props(bucket)
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
472
479
|
# Enables or disables SSL on all nodes, for HTTP backends.
|
473
480
|
def ssl=(value)
|
474
481
|
@nodes.each do |node|
|
@@ -126,6 +126,7 @@ module Riak
|
|
126
126
|
|
127
127
|
def get_index(bucket, index, query)
|
128
128
|
return super unless pb_indexes?
|
129
|
+
bucket = bucket.name if Bucket === bucket
|
129
130
|
if Range === query
|
130
131
|
options = {
|
131
132
|
:qtype => RpbIndexReq::IndexQueryType::RANGE,
|
@@ -218,7 +219,12 @@ module Riak
|
|
218
219
|
end
|
219
220
|
|
220
221
|
def decode_doc(doc)
|
221
|
-
Hash[doc.properties.map {|p| [ p.key, p.value ] }]
|
222
|
+
Hash[doc.properties.map {|p| [ force_utf8(p.key), force_utf8(p.value) ] }]
|
223
|
+
end
|
224
|
+
|
225
|
+
def force_utf8(str)
|
226
|
+
# Search returns strings that should always be valid UTF-8
|
227
|
+
ObjectMethods::ENCODING ? str.force_encoding('UTF-8') : str
|
222
228
|
end
|
223
229
|
end
|
224
230
|
end
|
@@ -150,12 +150,22 @@ module Riak
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def connection
|
153
|
-
@connection ||=
|
154
|
-
|
155
|
-
|
153
|
+
@connection ||= new_connection
|
154
|
+
end
|
155
|
+
|
156
|
+
def new_connection
|
157
|
+
params = { :read_timeout => self.class.read_timeout,
|
156
158
|
:write_timeout => self.class.write_timeout,
|
157
|
-
:connect_timeout => self.class.connect_timeout
|
158
|
-
|
159
|
+
:connect_timeout => self.class.connect_timeout }
|
160
|
+
args = [ params ]
|
161
|
+
if self.class.minimum_version?("0.19.0")
|
162
|
+
params.merge!(:scheme => root_uri.scheme,
|
163
|
+
:host => root_uri.host,
|
164
|
+
:port => root_uri.port)
|
165
|
+
else
|
166
|
+
args.unshift root_uri.to_s
|
167
|
+
end
|
168
|
+
Excon::Connection.new(*args)
|
159
169
|
end
|
160
170
|
end
|
161
171
|
end
|
@@ -13,7 +13,8 @@ module Riak
|
|
13
13
|
VERSION = {
|
14
14
|
1 => Gem::Version.new("1.0.0"),
|
15
15
|
1.1 => Gem::Version.new("1.1.0"),
|
16
|
-
1.2 => Gem::Version.new("1.2.0")
|
16
|
+
1.2 => Gem::Version.new("1.2.0"),
|
17
|
+
1.3 => Gem::Version.new("1.3.0")
|
17
18
|
}.freeze
|
18
19
|
|
19
20
|
# @return [String] the version of the Riak node
|
@@ -71,6 +72,12 @@ module Riak
|
|
71
72
|
at_least? VERSION[1]
|
72
73
|
end
|
73
74
|
|
75
|
+
# @return [true,false] whether bucket properties can be cleared
|
76
|
+
# (reset to defaults) over HTTP
|
77
|
+
def http_props_clearable?
|
78
|
+
at_least? VERSION[1.3]
|
79
|
+
end
|
80
|
+
|
74
81
|
protected
|
75
82
|
# @return [true,false] whether the server version is the same or
|
76
83
|
# newer than the requested version
|
@@ -133,6 +133,22 @@ module Riak
|
|
133
133
|
put(204, bucket_properties_path(bucket), body, {"Content-Type" => "application/json"})
|
134
134
|
end
|
135
135
|
|
136
|
+
# Clears bucket properties
|
137
|
+
# @param [Bucket, String] bucket the bucket to clear properties
|
138
|
+
# on
|
139
|
+
# @return [true, false] whether the operation succeeded
|
140
|
+
# @note false will be returned if the operation is not supported
|
141
|
+
# on the connected node
|
142
|
+
def clear_bucket_props(bucket)
|
143
|
+
if http_props_clearable?
|
144
|
+
bucket = bucket.name if Bucket === bucket
|
145
|
+
delete(204, bucket_properties_path(bucket))
|
146
|
+
true
|
147
|
+
else
|
148
|
+
false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
136
152
|
# List keys in a bucket
|
137
153
|
# @param [Bucket, String] bucket the bucket to fetch the keys
|
138
154
|
# for
|
@@ -53,7 +53,7 @@ module Riak
|
|
53
53
|
raise ArgumentError, t("stored_function_invalid") unless type == :link || value.has_key?(:bucket) && value.has_key?(:key)
|
54
54
|
@language = "javascript"
|
55
55
|
when String
|
56
|
-
@language = "javascript"
|
56
|
+
@language = (value =~ /\s*fun\s*\(.*\)\s*->/) ? "erlang" : "javascript"
|
57
57
|
when WalkSpec
|
58
58
|
raise ArgumentError, t("walk_spec_invalid_unless_link") unless type == :link
|
59
59
|
else
|
@@ -78,7 +78,7 @@ module Riak
|
|
78
78
|
when Hash
|
79
79
|
defaults.merge(function)
|
80
80
|
when String
|
81
|
-
if function =~ /\s*function/
|
81
|
+
if function =~ /\s*function\s*\(/ || function =~ /\s*fun\s*\(.*\)\s*->/
|
82
82
|
defaults.merge("source" => function)
|
83
83
|
else
|
84
84
|
defaults.merge("name" => function)
|
data/lib/riak/version.rb
CHANGED
data/lib/riak/walk_spec.rb
CHANGED
@@ -12,6 +12,7 @@ module Riak
|
|
12
12
|
# Riak::WalkSpec.new({:bucket => 'tracks', :result => true})
|
13
13
|
class WalkSpec
|
14
14
|
include Util::Translation
|
15
|
+
extend Util::Translation
|
15
16
|
include Util::Escape
|
16
17
|
|
17
18
|
# @return [String] The bucket followed links should be restricted to. "_" represents all buckets.
|
data/riak-client.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.authors = ["Sean Cribbs"]
|
13
13
|
|
14
14
|
# Deps
|
15
|
-
gem.add_development_dependency "rspec", "~>2.
|
15
|
+
gem.add_development_dependency "rspec", "~>2.13.0"
|
16
16
|
gem.add_development_dependency "fakeweb", ">=1.2"
|
17
17
|
gem.add_development_dependency "rack", ">=1.0"
|
18
18
|
gem.add_development_dependency "excon", ">=0.6.1"
|
@@ -37,6 +37,21 @@ describe "HTTP" do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
context "clearing bucket properties" do
|
41
|
+
it "should return false when unsupported", :version => "< 1.3.0" do
|
42
|
+
@backend.clear_bucket_props('foo').should be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should reset a previously set property to the default", :version => ">= 1.3.0" do
|
46
|
+
bucket = @client['bucketpropscleartest']
|
47
|
+
original_n = @backend.get_bucket_props(bucket)['n_val']
|
48
|
+
@backend.set_bucket_props(bucket, {'n_val' => 2})
|
49
|
+
@backend.get_bucket_props(bucket)['n_val'].should == 2
|
50
|
+
@backend.clear_bucket_props(bucket)
|
51
|
+
@backend.get_bucket_props(bucket)['n_val'].should == original_n
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
40
55
|
context "using Luwak", :version => "< 1.1.0" do
|
41
56
|
let(:file) { File.open(__FILE__) }
|
42
57
|
let(:key) { "spec.rb" }
|
@@ -30,6 +30,20 @@ describe "Protocol Buffers" do
|
|
30
30
|
results['docs'].should include({"id" => "munchausen-605"})
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
if "".respond_to?(:encoding) # Ruby 1.9 and later only
|
35
|
+
describe "searching fulltext indexes (1.2 and later)", :version => '>= 1.2.0' do
|
36
|
+
include_context "search corpus setup"
|
37
|
+
|
38
|
+
it 'should return documents with UTF-8 fields (GH #75)' do
|
39
|
+
utf8 = Encoding.find('UTF-8')
|
40
|
+
results = @backend.search 'search_test', 'fearless elephant rushed'
|
41
|
+
results['docs'].each do |d|
|
42
|
+
d.each {|(k,v)| k.encoding.should == utf8; v.encoding.should == utf8 }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|
data/spec/riak/bucket_spec.rb
CHANGED
@@ -86,6 +86,14 @@ describe Riak::Bucket do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
describe "clearing the bucket properties" do
|
90
|
+
it "should make the request and delete the internal properties cache" do
|
91
|
+
@client.should_receive(:clear_bucket_props).with(@bucket).and_return(true)
|
92
|
+
@bucket.clear_props.should be_true
|
93
|
+
@bucket.instance_variable_get(:@props).should be_nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
89
97
|
describe "fetching an object" do
|
90
98
|
it "should fetch the object via the backend" do
|
91
99
|
@backend.should_receive(:fetch_object).with(@bucket, "db", {}).and_return(nil)
|
@@ -24,6 +24,7 @@ describe Riak::Client::FeatureDetection do
|
|
24
24
|
it { should_not be_quorum_controls }
|
25
25
|
it { should_not be_tombstone_vclocks }
|
26
26
|
it { should_not be_pb_head }
|
27
|
+
it { should_not be_http_props_clearable }
|
27
28
|
end
|
28
29
|
|
29
30
|
context "when the Riak version is 1.0.x" do
|
@@ -35,6 +36,7 @@ describe Riak::Client::FeatureDetection do
|
|
35
36
|
it { should be_quorum_controls }
|
36
37
|
it { should be_tombstone_vclocks }
|
37
38
|
it { should be_pb_head }
|
39
|
+
it { should_not be_http_props_clearable }
|
38
40
|
end
|
39
41
|
|
40
42
|
context "when the Riak version is 1.1.x" do
|
@@ -46,10 +48,11 @@ describe Riak::Client::FeatureDetection do
|
|
46
48
|
it { should be_quorum_controls }
|
47
49
|
it { should be_tombstone_vclocks }
|
48
50
|
it { should be_pb_head }
|
51
|
+
it { should_not be_http_props_clearable }
|
49
52
|
end
|
50
53
|
|
51
54
|
context "when the Riak version is 1.2.x" do
|
52
|
-
before { subject.stub!(:get_server_version).and_return("1.2.
|
55
|
+
before { subject.stub!(:get_server_version).and_return("1.2.1") }
|
53
56
|
it { should be_mapred_phaseless }
|
54
57
|
it { should be_pb_indexes }
|
55
58
|
it { should be_pb_search }
|
@@ -57,5 +60,18 @@ describe Riak::Client::FeatureDetection do
|
|
57
60
|
it { should be_quorum_controls }
|
58
61
|
it { should be_tombstone_vclocks }
|
59
62
|
it { should be_pb_head }
|
63
|
+
it { should_not be_http_props_clearable }
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when the Riak version is 1.3.x" do
|
67
|
+
before { subject.stub!(:get_server_version).and_return("1.3.0") }
|
68
|
+
it { should be_mapred_phaseless }
|
69
|
+
it { should be_pb_indexes }
|
70
|
+
it { should be_pb_search }
|
71
|
+
it { should be_pb_conditionals }
|
72
|
+
it { should be_quorum_controls }
|
73
|
+
it { should be_tombstone_vclocks }
|
74
|
+
it { should be_pb_head }
|
75
|
+
it { should be_http_props_clearable }
|
60
76
|
end
|
61
77
|
end
|
@@ -2,13 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Riak::MapReduce::Phase do
|
4
4
|
before :each do
|
5
|
-
@
|
5
|
+
@js_fun = "function(v,_,_){ return v['values'][0]['data']; }"
|
6
|
+
@erl_fun = "fun(Obj, _KeyData, _Arg) -> [{riak_object:key(Obj), riak_object:get_value(Obj)}] end."
|
6
7
|
end
|
7
8
|
|
8
9
|
it "should initialize with a type and a function" do
|
9
|
-
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @
|
10
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @js_fun, :language => "javascript")
|
10
11
|
phase.type.should == :map
|
11
|
-
phase.function.should == @
|
12
|
+
phase.function.should == @js_fun
|
12
13
|
phase.language.should == "javascript"
|
13
14
|
end
|
14
15
|
|
@@ -31,11 +32,16 @@ describe Riak::MapReduce::Phase do
|
|
31
32
|
phase.language.should == "erlang"
|
32
33
|
end
|
33
34
|
|
34
|
-
it "should assume the language is javascript when the function is a string" do
|
35
|
-
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @
|
35
|
+
it "should assume the language is javascript when the function is a string and starts with function" do
|
36
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @js_fun)
|
36
37
|
phase.language.should == "javascript"
|
37
38
|
end
|
38
39
|
|
40
|
+
it "should assume the language is erlang when the function is a string and starts with anon fun" do
|
41
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @erl_fun)
|
42
|
+
phase.language.should == "erlang"
|
43
|
+
end
|
44
|
+
|
39
45
|
it "should assume the language is javascript when the function is a hash" do
|
40
46
|
phase = Riak::MapReduce::Phase.new(:type => :map, :function => {:bucket => "jobs", :key => "awesome_map"})
|
41
47
|
phase.language.should == "javascript"
|
data/spec/riak/walk_spec_spec.rb
CHANGED
@@ -101,6 +101,10 @@ describe Riak::WalkSpec do
|
|
101
101
|
specs.should be_all {|s| s.kind_of?(Riak::WalkSpec) }
|
102
102
|
specs.join("/").should == "_,next,_/foo,_,_/_,child,1"
|
103
103
|
end
|
104
|
+
|
105
|
+
it "should raise an error when given invalid number of parameters" do
|
106
|
+
expect { Riak::WalkSpec.normalize("foo") }.to raise_error(ArgumentError)
|
107
|
+
end
|
104
108
|
end
|
105
109
|
|
106
110
|
describe "matching other objects with ===" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riak-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
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: 2013-
|
12
|
+
date: 2013-05-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 2.
|
21
|
+
version: 2.13.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 2.
|
29
|
+
version: 2.13.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: fakeweb
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -329,12 +329,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
329
329
|
- - ! '>='
|
330
330
|
- !ruby/object:Gem::Version
|
331
331
|
version: '0'
|
332
|
+
segments:
|
333
|
+
- 0
|
334
|
+
hash: 20034304450029998
|
332
335
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
333
336
|
none: false
|
334
337
|
requirements:
|
335
338
|
- - ! '>='
|
336
339
|
- !ruby/object:Gem::Version
|
337
340
|
version: '0'
|
341
|
+
segments:
|
342
|
+
- 0
|
343
|
+
hash: 20034304450029998
|
338
344
|
requirements: []
|
339
345
|
rubyforge_project:
|
340
346
|
rubygems_version: 1.8.23
|