riak-client 0.8.0.beta2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/riak.rb +1 -0
- data/lib/riak/bucket.rb +4 -2
- data/lib/riak/cache_store.rb +4 -0
- data/lib/riak/client/curb_backend.rb +20 -3
- data/lib/riak/client/http_backend.rb +1 -0
- data/lib/riak/map_reduce.rb +1 -1
- data/lib/riak/robject.rb +13 -9
- data/lib/riak/util/escape.rb +16 -0
- data/lib/riak/util/headers.rb +3 -1
- data/lib/riak/util/translation.rb +3 -0
- data/lib/riak/walk_spec.rb +0 -1
- data/spec/riak/curb_backend_spec.rb +25 -1
- data/spec/riak/escape_spec.rb +14 -0
- data/spec/support/mocks.rb +15 -1
- metadata +6 -9
data/lib/riak.rb
CHANGED
data/lib/riak/bucket.rb
CHANGED
@@ -177,7 +177,8 @@ module Riak
|
|
177
177
|
def n_value
|
178
178
|
props['n_val']
|
179
179
|
end
|
180
|
-
|
180
|
+
alias :n_val :n_value
|
181
|
+
|
181
182
|
# Set the N value (number of replicas). *NOTE* This will result in a PUT request to Riak.
|
182
183
|
# Setting this value after the bucket has objects stored in it may have unpredictable results.
|
183
184
|
# @param [Fixnum] value the number of replicas the bucket should keep of each object
|
@@ -185,7 +186,8 @@ module Riak
|
|
185
186
|
self.props = {'n_val' => value}
|
186
187
|
value
|
187
188
|
end
|
188
|
-
|
189
|
+
alias :n_val= :n_value=
|
190
|
+
|
189
191
|
[:r,:w,:dw,:rw].each do |q|
|
190
192
|
class_eval <<-CODE
|
191
193
|
def #{q}
|
data/lib/riak/cache_store.rb
CHANGED
@@ -12,10 +12,14 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
require 'riak'
|
15
|
+
|
15
16
|
module Riak
|
17
|
+
# An ActiveSupport::Cache::Store implementation that uses Riak.
|
18
|
+
# Compatible only with ActiveSupport version 3 or greater.
|
16
19
|
class CacheStore < ActiveSupport::Cache::Store
|
17
20
|
attr_accessor :client
|
18
21
|
|
22
|
+
# Creates a Riak-backed cache store.
|
19
23
|
def initialize(options = {})
|
20
24
|
super
|
21
25
|
@bucket_name = options.delete(:bucket) || '_cache'
|
@@ -29,7 +29,7 @@ module Riak
|
|
29
29
|
private
|
30
30
|
def perform(method, uri, headers, expect, data=nil)
|
31
31
|
# Setup
|
32
|
-
curl.headers = headers
|
32
|
+
curl.headers = create_request_headers(headers)
|
33
33
|
curl.url = uri.to_s
|
34
34
|
response_headers.initialize_http_header(nil)
|
35
35
|
if block_given?
|
@@ -46,8 +46,15 @@ module Riak
|
|
46
46
|
end
|
47
47
|
# Perform
|
48
48
|
case method
|
49
|
-
when :
|
50
|
-
|
49
|
+
when :post
|
50
|
+
data = data.read if data.respond_to?(:read)
|
51
|
+
curl.http_post(data)
|
52
|
+
when :put
|
53
|
+
# Hacks around limitations in curb's PUT semantics
|
54
|
+
_headers, curl.headers = curl.headers, {}
|
55
|
+
curl.put_data = data
|
56
|
+
curl.headers = create_request_headers(curl.headers) + _headers
|
57
|
+
curl.http("PUT")
|
51
58
|
else
|
52
59
|
curl.send("http_#{method}")
|
53
60
|
end
|
@@ -77,6 +84,16 @@ module Riak
|
|
77
84
|
def response_headers
|
78
85
|
Thread.current[:response_headers] ||= Riak::Util::Headers.new
|
79
86
|
end
|
87
|
+
|
88
|
+
def create_request_headers(hash)
|
89
|
+
h = Riak::Util::Headers.new
|
90
|
+
hash.each {|k,v| h.add_field(k,v) }
|
91
|
+
[].tap do |arr|
|
92
|
+
h.each_capitalized do |k,v|
|
93
|
+
arr << "#{k}: #{v}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
80
97
|
end
|
81
98
|
end
|
82
99
|
end
|
data/lib/riak/map_reduce.rb
CHANGED
@@ -161,7 +161,7 @@ module Riak
|
|
161
161
|
end
|
162
162
|
|
163
163
|
# Represents an individual phase in a map-reduce pipeline. Generally you'll want to call
|
164
|
-
# methods of
|
164
|
+
# methods of MapReduce instead of using this directly.
|
165
165
|
class Phase
|
166
166
|
include Util::Translation
|
167
167
|
# @return [Symbol] the type of phase - :map, :reduce, or :link
|
data/lib/riak/robject.rb
CHANGED
@@ -15,8 +15,8 @@ require 'riak'
|
|
15
15
|
require 'set'
|
16
16
|
|
17
17
|
module Riak
|
18
|
-
#
|
19
|
-
# the
|
18
|
+
# Represents the data and metadata stored in a bucket/key pair in
|
19
|
+
# the Riak database, the base unit of data manipulation.
|
20
20
|
class RObject
|
21
21
|
include Util
|
22
22
|
include Util::Translation
|
@@ -52,10 +52,8 @@ module Riak
|
|
52
52
|
|
53
53
|
# Loads a list of RObjects that were emitted from a MapReduce
|
54
54
|
# query.
|
55
|
-
# @param [Client] client A Riak::Client with which the results will be
|
56
|
-
#
|
57
|
-
# @param [Array<Hash>] response A list of results a MapReduce job. Each
|
58
|
-
# entry should contain these keys: bucket, key, vclock, values
|
55
|
+
# @param [Client] client A Riak::Client with which the results will be associated
|
56
|
+
# @param [Array<Hash>] response A list of results a MapReduce job. Each entry should contain these keys: bucket, key, vclock, values
|
59
57
|
# @return [Array<RObject>] An array of RObject instances
|
60
58
|
def self.load_from_mapreduce(client, response)
|
61
59
|
response.map do |item|
|
@@ -66,6 +64,7 @@ module Riak
|
|
66
64
|
# Create a new object manually
|
67
65
|
# @param [Bucket] bucket the bucket in which the object exists
|
68
66
|
# @param [String] key the key at which the object resides. If nil, a key will be assigned when the object is saved.
|
67
|
+
# @yield self the new RObject
|
69
68
|
# @see Bucket#get
|
70
69
|
def initialize(bucket, key=nil)
|
71
70
|
@bucket, @key = bucket, key
|
@@ -205,7 +204,9 @@ module Riak
|
|
205
204
|
# Automatically serialized formats:
|
206
205
|
# * JSON (application/json)
|
207
206
|
# * YAML (text/yaml)
|
208
|
-
# * Marshal (application/
|
207
|
+
# * Marshal (application/x-ruby-marshal)
|
208
|
+
# When given an IO-like object (e.g. File), no serialization will
|
209
|
+
# be done.
|
209
210
|
# @param [Object] payload the data to serialize
|
210
211
|
def serialize(payload)
|
211
212
|
return payload if IO === payload
|
@@ -226,7 +227,7 @@ module Riak
|
|
226
227
|
# Automatically deserialized formats:
|
227
228
|
# * JSON (application/json)
|
228
229
|
# * YAML (text/yaml)
|
229
|
-
# * Marshal (application/
|
230
|
+
# * Marshal (application/x-ruby-marshal)
|
230
231
|
# @param [String] body the serialized response body
|
231
232
|
def deserialize(body)
|
232
233
|
case @content_type
|
@@ -247,6 +248,7 @@ module Riak
|
|
247
248
|
end
|
248
249
|
|
249
250
|
# Walks links from this object to other objects in Riak.
|
251
|
+
# @param [Array<Hash,WalkSpec>] link specifications for the query
|
250
252
|
def walk(*params)
|
251
253
|
specs = WalkSpec.normalize(*params)
|
252
254
|
response = @bucket.client.http.get(200, @bucket.client.prefix, escape(@bucket.name), escape(@key), specs.join("/"))
|
@@ -259,7 +261,9 @@ module Riak
|
|
259
261
|
end
|
260
262
|
end
|
261
263
|
|
262
|
-
# Converts the object to a link suitable for linking other objects
|
264
|
+
# Converts the object to a link suitable for linking other objects
|
265
|
+
# to it
|
266
|
+
# @param [String] tag the tag to apply to the link
|
263
267
|
def to_link(tag)
|
264
268
|
Link.new(@bucket.client.http.path(@bucket.client.prefix, escape(@bucket.name), escape(@key)).path, tag)
|
265
269
|
end
|
data/lib/riak/util/escape.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'riak'
|
15
|
+
|
1
16
|
module Riak
|
2
17
|
module Util
|
18
|
+
# Methods for escaping URL segments.
|
3
19
|
module Escape
|
4
20
|
# CGI-escapes bucket or key names that may contain slashes for use in URLs.
|
5
21
|
# @param [String] bucket_or_key the bucket or key name
|
data/lib/riak/util/headers.rb
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
require 'riak'
|
15
15
|
|
16
16
|
# Splits headers into < 8KB chunks
|
17
|
+
# @private
|
17
18
|
module Net::HTTPHeader
|
18
19
|
def each_capitalized
|
19
20
|
# 1.9 check
|
@@ -35,7 +36,8 @@ end
|
|
35
36
|
|
36
37
|
module Riak
|
37
38
|
module Util
|
38
|
-
# Represents headers from an HTTP response
|
39
|
+
# Represents headers from an HTTP request or response.
|
40
|
+
# Used internally by HTTP backends for processing headers.
|
39
41
|
class Headers
|
40
42
|
include Net::HTTPHeader
|
41
43
|
|
@@ -15,11 +15,14 @@ require 'riak'
|
|
15
15
|
|
16
16
|
module Riak
|
17
17
|
module Util
|
18
|
+
# Methods for doing i18n string lookup
|
18
19
|
module Translation
|
20
|
+
# The scope of i18n messages
|
19
21
|
def i18n_scope
|
20
22
|
:riak
|
21
23
|
end
|
22
24
|
|
25
|
+
# Provides the translation for a given internationalized message
|
23
26
|
def t(message, options={})
|
24
27
|
I18n.t("#{i18n_scope}.#{message}", options)
|
25
28
|
end
|
data/lib/riak/walk_spec.rb
CHANGED
@@ -20,7 +20,7 @@ rescue LoadError
|
|
20
20
|
else
|
21
21
|
$server = MockServer.new
|
22
22
|
at_exit { $server.stop }
|
23
|
-
|
23
|
+
|
24
24
|
describe Riak::Client::CurbBackend do
|
25
25
|
def setup_http_mock(method, uri, options={})
|
26
26
|
method = method.to_s.upcase
|
@@ -46,8 +46,32 @@ else
|
|
46
46
|
|
47
47
|
it_should_behave_like "HTTP backend"
|
48
48
|
|
49
|
+
it "should split long headers into 8KB chunks" do
|
50
|
+
setup_http_mock(:put, @backend.path("/riak/","foo").to_s, :body => "ok")
|
51
|
+
lambda do
|
52
|
+
@backend.put(200, "/riak/", "foo", "body",{"Long-Header" => (["12345678"*10]*100).join(", ") })
|
53
|
+
headers = @backend.send(:curl).headers
|
54
|
+
headers.should be_kind_of(Array)
|
55
|
+
headers.select {|h| h =~ /^Long-Header:/ }.should have(2).items
|
56
|
+
headers.select {|h| h =~ /^Long-Header:/ }.should be_all {|h| h.size < 8192 }
|
57
|
+
end.should_not raise_error
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should support IO objects as the request body" do
|
61
|
+
file = File.open(File.expand_path("../../fixtures/cat.jpg", __FILE__))
|
62
|
+
lambda do
|
63
|
+
setup_http_mock(:put, @backend.path("/riak/","foo").to_s, :body => "ok")
|
64
|
+
@backend.put(200, "/riak/", "foo", file,{})
|
65
|
+
end.should_not raise_error
|
66
|
+
lambda do
|
67
|
+
setup_http_mock(:post, @backend.path("/riak/","foo").to_s, :body => "ok")
|
68
|
+
@backend.post(200, "/riak/", "foo", file, {})
|
69
|
+
end.should_not raise_error
|
70
|
+
end
|
71
|
+
|
49
72
|
after :each do
|
50
73
|
$server.detach
|
74
|
+
Thread.current[:curl_easy_handle] = nil
|
51
75
|
end
|
52
76
|
end
|
53
77
|
end
|
data/spec/riak/escape_spec.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
1
15
|
require File.expand_path("../../spec_helper", __FILE__)
|
2
16
|
|
3
17
|
describe Riak::Util::Escape do
|
data/spec/support/mocks.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
1
15
|
def mock_response(overrides={})
|
2
16
|
{:headers => {"content-type" => ["application/json"]}, :body => '{}'}.merge(overrides)
|
3
|
-
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riak-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 8
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.8.0.beta2
|
9
|
+
version: 0.8.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Sean Cribbs
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-31 00:00:00 -04:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -181,13 +180,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
181
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
181
|
none: false
|
183
182
|
requirements:
|
184
|
-
- - "
|
183
|
+
- - ">="
|
185
184
|
- !ruby/object:Gem::Version
|
186
185
|
segments:
|
187
|
-
-
|
188
|
-
|
189
|
-
- 1
|
190
|
-
version: 1.3.1
|
186
|
+
- 0
|
187
|
+
version: "0"
|
191
188
|
requirements:
|
192
189
|
- `gem install curb` for better HTTP performance
|
193
190
|
rubyforge_project:
|