riak-client 0.8.2 → 0.8.3

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.
@@ -20,10 +20,19 @@ module Riak
20
20
  # be preferred when the 'curb' library is available.
21
21
  # Conforms to the Riak::Client::HTTPBackend interface.
22
22
  class NetHTTPBackend < HTTPBackend
23
+ def self.configured?
24
+ begin
25
+ require 'net/http'
26
+ true
27
+ rescue LoadError, NameError
28
+ false
29
+ end
30
+ end
31
+
23
32
  private
24
33
  def perform(method, uri, headers, expect, data=nil) #:nodoc:
25
34
  Net::HTTP.start(uri.host, uri.port) do |http|
26
- request = Net::HTTP.const_get(method.to_s.camelize).new(uri.request_uri, headers)
35
+ request = Net::HTTP.const_get(method.to_s.capitalize).new(uri.request_uri, headers)
27
36
  case data
28
37
  when String
29
38
  request.body = data
@@ -40,7 +49,7 @@ module Riak
40
49
  result[:body] = response.body
41
50
  end
42
51
  else
43
- raise FailedRequest.new(method, expect, response.code, response.to_hash, response.body)
52
+ raise FailedRequest.new(method, expect, response.code.to_i, response.to_hash, response.body)
44
53
  end
45
54
  end
46
55
  end
@@ -0,0 +1,6 @@
1
+ require 'riak/core_ext/blank'
2
+ require 'riak/core_ext/extract_options'
3
+ require 'riak/core_ext/slice'
4
+ require 'riak/core_ext/stringify_keys'
5
+ require 'riak/core_ext/symbolize_keys'
6
+ require 'riak/core_ext/to_param'
@@ -0,0 +1,39 @@
1
+ unless Object.new.respond_to? :blank?
2
+ class Object
3
+ def blank?
4
+ false
5
+ end
6
+ end
7
+
8
+ class NilClass
9
+ def blank?
10
+ true
11
+ end
12
+ end
13
+
14
+ class Set
15
+ alias :blank? :empty?
16
+ end
17
+
18
+ class String
19
+ def blank?
20
+ not self =~ /[^\s]/
21
+ end
22
+ end
23
+
24
+ class Array
25
+ alias :blank? :empty?
26
+ end
27
+
28
+ class Hash
29
+ alias :blank? :empty?
30
+ end
31
+ end
32
+
33
+ unless Object.new.respond_to? :present?
34
+ class Object
35
+ def present?
36
+ not blank?
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ unless Array.new.respond_to? :extract_options!
2
+ class Array
3
+ def extract_options!
4
+ last.is_a?(::Hash) ? pop : {}
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ unless {}.respond_to? :slice
2
+ class Hash
3
+ def slice(*keys)
4
+ allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
5
+ hash = {}
6
+ allowed.each { |k| hash[k] = self[k] if has_key?(k) }
7
+ hash
8
+ end
9
+
10
+ def slice!(*keys)
11
+ keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
12
+ omit = slice(*self.keys - keys)
13
+ hash = slice(*keys)
14
+ replace(hash)
15
+ omit
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ unless {}.respond_to? :stringify_keys
2
+ class Hash
3
+ def stringify_keys
4
+ inject({}) do |hash, pair|
5
+ hash[pair[0].to_s] = pair[1]
6
+ hash
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ unless {}.respond_to? :symbolize_keys
2
+ class Hash
3
+ def symbolize_keys
4
+ inject({}) do |hash, pair|
5
+ hash[pair[0].to_sym] = pair[1]
6
+ hash
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ unless Object.new.respond_to? :to_query and Object.new.respond_to? :to_param
2
+ class Object
3
+ def to_param
4
+ to_s
5
+ end
6
+
7
+ def to_query(key)
8
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
9
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
10
+ end
11
+ end
12
+
13
+ class Array
14
+ def to_param
15
+ map(&:to_param).join('/')
16
+ end
17
+
18
+ def to_query(key)
19
+ prefix = "#{key}[]"
20
+ collect { |value| value.to_query(prefix) }.join '&'
21
+ end
22
+ end
23
+
24
+ class Hash
25
+ def to_param
26
+ map do |key, value|
27
+ value.to_query(key)
28
+ end.sort * '&'
29
+ end
30
+ end
31
+ end
data/lib/riak/i18n.rb CHANGED
@@ -11,10 +11,6 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- if ActiveSupport::VERSION::STRING >= "3.0"
15
- require 'active_support/i18n'
16
- else
17
- require 'i18n' # support ActiveSupport < 3
18
- end
14
+ require 'i18n'
19
15
 
20
16
  I18n.load_path << File.expand_path("../locale/en.yml", __FILE__)
data/lib/riak/link.rb CHANGED
@@ -17,13 +17,18 @@ module Riak
17
17
  # Represents a link from one object to another in Riak
18
18
  class Link
19
19
  include Util::Translation
20
- # @return [String] the URL (relative or absolute) of the related resource
21
- attr_accessor :url
20
+ include Util::Escape
21
+
22
+ # @return [String] the relationship tag (or "rel") of the other resource to this one
23
+ attr_accessor :tag
24
+ alias_method :rel, :tag
25
+ alias_method :rel=, :tag=
26
+
27
+ # @return [String] the bucket of the related resource
28
+ attr_accessor :bucket
22
29
 
23
- # @return [String] the relationship ("rel") of the other resource to this one
24
- attr_accessor :rel
25
- alias :tag :rel
26
- alias :tag= :rel=
30
+ # @return [String] the key of the related resource
31
+ attr_accessor :key
27
32
 
28
33
  # @param [String] header_string the string value of the Link: HTTP header from a Riak response
29
34
  # @return [Array<Link>] an array of Riak::Link structs parsed from the header
@@ -33,24 +38,36 @@ module Riak
33
38
  end
34
39
  end
35
40
 
36
- def initialize(url, rel)
37
- @url, @rel = url, rel
41
+ # @overload initialize(url, tag)
42
+ # @param [String] url the url of the related resource
43
+ # @param [String] tag the tag for the related resource
44
+ # @overload initialize(bucket, key, tag)
45
+ # @param [String] bucket the bucket of the related resource
46
+ # @param [String] key the key of the related resource
47
+ # @param [String] tag the tag for the related resource
48
+ def initialize(*args)
49
+ raise ArgumentError unless (2..3).include?(args.size)
50
+ if args.size == 2
51
+ self.url, @tag = args
52
+ else
53
+ @bucket, @key, @tag = args
54
+ end
38
55
  end
39
56
 
40
- # @return [String] bucket_name, if the Link url is a known Riak link ("/riak/<bucket>/<key>")
41
- def bucket
42
- CGI.unescape($1) if url =~ %r{^/[^/]+/([^/]+)/?}
57
+ # @return [String] the URL (relative or absolute) of the related resource
58
+ def url
59
+ "/riak/#{escape(bucket)}" + (key.blank? ? "" : "/#{escape(key)}")
43
60
  end
44
-
45
- # @return [String] key, if the Link url is a known Riak link ("/riak/<bucket>/<key>")
46
- def key
47
- CGI.unescape($1) if url =~ %r{^/[^/]+/[^/]+/([^/]+)/?}
61
+
62
+ def url=(value)
63
+ @bucket = CGI.unescape($1) if value =~ %r{^/[^/]+/([^/]+)/?}
64
+ @key = CGI.unescape($1) if value =~ %r{^/[^/]+/[^/]+/([^/]+)/?}
48
65
  end
49
66
 
50
67
  def inspect; to_s; end
51
68
 
52
69
  def to_s
53
- %Q[<#{@url}>; riaktag="#{@rel}"]
70
+ %Q[<#{url}>; riaktag="#{tag}"]
54
71
  end
55
72
 
56
73
  def hash
@@ -62,12 +79,12 @@ module Riak
62
79
  end
63
80
 
64
81
  def ==(other)
65
- other.is_a?(Link) && url == other.url && rel == other.rel
82
+ other.is_a?(Link) && url == other.url && tag == other.tag
66
83
  end
67
84
 
68
85
  def to_walk_spec
69
- raise t("bucket_link_conversion") if @rel == "up" || key.nil?
70
- WalkSpec.new(:bucket => bucket, :tag => @rel)
86
+ raise t("bucket_link_conversion") if tag == "up" || key.nil?
87
+ WalkSpec.new(:bucket => bucket, :tag => tag)
71
88
  end
72
89
  end
73
90
  end
@@ -19,8 +19,8 @@ en:
19
19
  empty_map_reduce_query: "Specify one or more query phases to your MapReduce."
20
20
  failed_request: "Expected %{expected} from Riak but received %{code}. %{body}"
21
21
  hash_type: "invalid argument %{hash} is not a Hash"
22
+ http_configuration: "The %{backend} HTTP backend cannot be used. Please check its requirements."
22
23
  hostname_invalid: "host must be a valid hostname"
23
- install_curb: "curb library not found! Please `gem install curb` for better performance."
24
24
  invalid_client_id: "Invalid client ID, must be a string or between 0 and %{max_id}"
25
25
  invalid_function_value: "invalid value for function: %{value}"
26
26
  invalid_phase_type: "type must be :map, :reduce, or :link"
@@ -137,10 +137,10 @@ module Riak
137
137
 
138
138
  # Convert the job to JSON for submission over the HTTP interface.
139
139
  # @return [String] the JSON representation
140
- def to_json(options={})
141
- hash = {"inputs" => inputs.as_json, "query" => query.map(&:as_json)}
140
+ def to_json(*a)
141
+ hash = {"inputs" => inputs, "query" => query.map(&:as_json)}
142
142
  hash['timeout'] = @timeout.to_i if @timeout
143
- ActiveSupport::JSON.encode(hash, options)
143
+ hash.to_json(*a)
144
144
  end
145
145
 
146
146
  # Executes this map-reduce job.
@@ -148,9 +148,10 @@ module Riak
148
148
  def run
149
149
  raise MapReduceError.new(t("empty_map_reduce_query")) if @query.empty?
150
150
  response = @client.http.post(200, @client.mapred, to_json, {"Content-Type" => "application/json", "Accept" => "application/json"})
151
- if response.try(:[], :headers).try(:[],'content-type').include?("application/json")
152
- ActiveSupport::JSON.decode(response[:body])
153
- else
151
+ begin
152
+ raise unless response[:headers]['content-type'].include?('application/json')
153
+ JSON.parse(response[:body])
154
+ rescue
154
155
  response
155
156
  end
156
157
  rescue FailedRequest => fr
@@ -220,8 +221,8 @@ module Riak
220
221
 
221
222
  # Converts the phase to JSON for use while invoking a job.
222
223
  # @return [String] a JSON representation of the phase
223
- def to_json(options=nil)
224
- ActiveSupport::JSON.encode(as_json, options)
224
+ def to_json(*a)
225
+ as_json.to_json(*a)
225
226
  end
226
227
 
227
228
  # Converts the phase to its JSON-compatible representation for job invocation.
data/lib/riak/robject.rb CHANGED
@@ -33,7 +33,6 @@ module Riak
33
33
 
34
34
  # @return [String] the Riak vector clock for the object
35
35
  attr_accessor :vclock
36
- alias_attribute :vector_clock, :vclock
37
36
 
38
37
  # @return [Set<Link>] a Set of {Riak::Link} objects for relationships between this object and other resources
39
38
  attr_accessor :links
@@ -88,7 +87,7 @@ module Riak
88
87
  end
89
88
  h
90
89
  end
91
- @conflict = response[:code].try(:to_i) == 300 && content_type =~ /multipart\/mixed/
90
+ @conflict = (response[:code].to_i == 300 && content_type =~ /multipart\/mixed/) rescue false
92
91
  @siblings = nil
93
92
  self.raw_data = response[:body] if response[:body].present?
94
93
  self
@@ -250,7 +249,7 @@ module Riak
250
249
  return payload if IO === payload
251
250
  case @content_type
252
251
  when /json/
253
- ActiveSupport::JSON.encode(payload)
252
+ payload.to_json
254
253
  when /yaml/
255
254
  YAML.dump(payload)
256
255
  when "application/x-ruby-marshal"
@@ -270,7 +269,7 @@ module Riak
270
269
  def deserialize(body)
271
270
  case @content_type
272
271
  when /json/
273
- ActiveSupport::JSON.decode(body)
272
+ JSON.parse(body)
274
273
  when /yaml/
275
274
  YAML.load(body)
276
275
  when "application/x-ruby-marshal"
@@ -282,7 +281,12 @@ module Riak
282
281
 
283
282
  # @return [String] A representation suitable for IRB and debugging output
284
283
  def inspect
285
- "#<#{self.class.name} #{url} [#{@content_type}]:#{@data.inspect}>"
284
+ body = if @data || content_type =~ /json|yaml|marshal/
285
+ data.inspect
286
+ else
287
+ @raw_data && "(#{@raw_data.size} bytes)"
288
+ end
289
+ "#<#{self.class.name} #{url} [#{@content_type}]:#{body}>"
286
290
  end
287
291
 
288
292
  # Walks links from this object to other objects in Riak.
@@ -303,7 +307,7 @@ module Riak
303
307
  # to it
304
308
  # @param [String] tag the tag to apply to the link
305
309
  def to_link(tag)
306
- Link.new(@bucket.client.http.path(@bucket.client.prefix, escape(@bucket.name), escape(@key)).path, tag)
310
+ Link.new(@bucket.name, @key, tag)
307
311
  end
308
312
 
309
313
  # Generates a URL representing the object according to the client, bucket and key.
@@ -315,6 +319,9 @@ module Riak
315
319
  @bucket.client.http.path(*segments).to_s
316
320
  end
317
321
 
322
+ alias :vector_clock :vclock
323
+ alias :vector_clock= :vclock=
324
+
318
325
  protected
319
326
  def load_map_reduce_value(hash)
320
327
  metadata = hash['metadata']
data/lib/riak/search.rb CHANGED
@@ -52,7 +52,7 @@ module Riak
52
52
  path = [solr, index, "select", {"q" => query, "wt" => "json"}.merge(options.stringify_keys), {}].compact
53
53
  response = http.get(200, *path)
54
54
  if response[:headers]['content-type'].include?("application/json")
55
- ActiveSupport::JSON.decode(response[:body])
55
+ JSON.parse(response[:body])
56
56
  else
57
57
  response[:body]
58
58
  end
@@ -98,7 +98,12 @@ module Riak
98
98
  # @raise [ArgumentError] if any document specs don't include 'id' or 'query' keys
99
99
  def remove(*args)
100
100
  index = args.shift if String === args.first
101
- raise ArgumentError.new(t("search_remove_requires_id_or_query")) unless args.all? {|s| s.stringify_keys.key?("id") || s.stringify_keys.key?("query") }
101
+ raise ArgumentError.new(t("search_remove_requires_id_or_query")) unless args.all? { |s|
102
+ s.include? :id or
103
+ s.include? 'id' or
104
+ s.include? :query or
105
+ s.include? 'query'
106
+ }
102
107
  xml = Builder::XmlMarkup.new
103
108
  xml.delete do
104
109
  args.each do |spec|
@@ -88,6 +88,7 @@ module Riak
88
88
  @mutex.synchronize do
89
89
  @cin, @cout, @cerr, @cpid = Open3.popen3("#{@riak_script} console")
90
90
  @cin.puts
91
+ @cin.flush
91
92
  wait_for_erlang_prompt
92
93
  @started = true
93
94
  end
@@ -100,6 +101,7 @@ module Riak
100
101
  @mutex.synchronize do
101
102
  begin
102
103
  @cin.puts "init:stop()."
104
+ @cin.flush
103
105
  rescue Errno::EPIPE
104
106
  ensure
105
107
  register_stop
@@ -122,9 +124,11 @@ module Riak
122
124
  begin
123
125
  if @app_config[:riak_kv][:storage_backend] == :riak_kv_test_backend
124
126
  @cin.puts "riak_kv_test_backend:reset()."
127
+ @cin.flush
125
128
  wait_for_erlang_prompt
126
129
  else
127
130
  @cin.puts "init:restart()."
131
+ @cin.flush
128
132
  wait_for_erlang_prompt
129
133
  wait_for_startup
130
134
  end
@@ -224,7 +228,7 @@ module Riak
224
228
  def register_stop
225
229
  %w{@cin @cout @cerr}.each {|io| if instance_variable_get(io); instance_variable_get(io).close; instance_variable_set(io, nil) end }
226
230
  _cpid = @cpid; @cpid = nil
227
- at_exit { _cpid.join if _cpid.alive? }
231
+ at_exit { _cpid.join if _cpid && _cpid.alive? }
228
232
  @started = false
229
233
  end
230
234
  end
@@ -0,0 +1,49 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{riak-client}
5
+ s.version = "0.8.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sean Cribbs"]
9
+ s.date = %q{2010-12-13}
10
+ s.description = %q{riak-client is a rich client for Riak, the distributed database by Basho. It supports the full HTTP interface including storage operations, bucket configuration, link-walking and map-reduce.}
11
+ s.email = %q{sean@basho.com}
12
+ s.files = ["erl_src/riak_kv_test_backend.beam", "erl_src/riak_kv_test_backend.erl", "Gemfile", "lib/active_support/cache/riak_store.rb", "lib/riak/bucket.rb", "lib/riak/cache_store.rb", "lib/riak/client/curb_backend.rb", "lib/riak/client/excon_backend.rb", "lib/riak/client/http_backend.rb", "lib/riak/client/net_http_backend.rb", "lib/riak/client.rb", "lib/riak/core_ext/blank.rb", "lib/riak/core_ext/extract_options.rb", "lib/riak/core_ext/slice.rb", "lib/riak/core_ext/stringify_keys.rb", "lib/riak/core_ext/symbolize_keys.rb", "lib/riak/core_ext/to_param.rb", "lib/riak/core_ext.rb", "lib/riak/failed_request.rb", "lib/riak/i18n.rb", "lib/riak/invalid_response.rb", "lib/riak/link.rb", "lib/riak/locale/en.yml", "lib/riak/map_reduce.rb", "lib/riak/map_reduce_error.rb", "lib/riak/robject.rb", "lib/riak/search.rb", "lib/riak/test_server.rb", "lib/riak/util/escape.rb", "lib/riak/util/fiber1.8.rb", "lib/riak/util/headers.rb", "lib/riak/util/multipart.rb", "lib/riak/util/tcp_socket_extensions.rb", "lib/riak/util/translation.rb", "lib/riak/walk_spec.rb", "lib/riak.rb", "Rakefile", "riak-client.gemspec", "spec/fixtures/cat.jpg", "spec/fixtures/multipart-blank.txt", "spec/fixtures/multipart-with-body.txt", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/object_spec.rb", "spec/riak/search_spec.rb", "spec/riak/walk_spec_spec.rb", "spec/spec_helper.rb", "spec/support/drb_mock_server.rb", "spec/support/http_backend_implementation_examples.rb", "spec/support/mock_server.rb", "spec/support/mocks.rb", "spec/support/test_server.yml.example"]
13
+ s.homepage = %q{http://seancribbs.github.com/ripple}
14
+ s.require_paths = ["lib"]
15
+ s.rubygems_version = %q{1.3.7}
16
+ s.summary = %q{riak-client is a rich client for Riak, the distributed database by Basho.}
17
+ s.test_files = ["lib/riak/walk_spec.rb", "spec/integration/riak/cache_store_spec.rb", "spec/integration/riak/test_server_spec.rb", "spec/riak/bucket_spec.rb", "spec/riak/client_spec.rb", "spec/riak/curb_backend_spec.rb", "spec/riak/escape_spec.rb", "spec/riak/excon_backend_spec.rb", "spec/riak/headers_spec.rb", "spec/riak/http_backend_spec.rb", "spec/riak/link_spec.rb", "spec/riak/map_reduce_spec.rb", "spec/riak/multipart_spec.rb", "spec/riak/net_http_backend_spec.rb", "spec/riak/object_spec.rb", "spec/riak/search_spec.rb", "spec/riak/walk_spec_spec.rb"]
18
+
19
+ if s.respond_to? :specification_version then
20
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
21
+ s.specification_version = 3
22
+
23
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
+ s.add_development_dependency(%q<rspec>, ["~> 2.0.0"])
25
+ s.add_development_dependency(%q<fakeweb>, [">= 1.2"])
26
+ s.add_development_dependency(%q<rack>, [">= 1.0"])
27
+ s.add_development_dependency(%q<curb>, [">= 0.6"])
28
+ s.add_development_dependency(%q<excon>, ["~> 0.3.4"])
29
+ s.add_runtime_dependency(%q<i18n>, [">= 0.4.0"])
30
+ s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
31
+ else
32
+ s.add_dependency(%q<rspec>, ["~> 2.0.0"])
33
+ s.add_dependency(%q<fakeweb>, [">= 1.2"])
34
+ s.add_dependency(%q<rack>, [">= 1.0"])
35
+ s.add_dependency(%q<curb>, [">= 0.6"])
36
+ s.add_dependency(%q<excon>, ["~> 0.3.4"])
37
+ s.add_dependency(%q<i18n>, [">= 0.4.0"])
38
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
39
+ end
40
+ else
41
+ s.add_dependency(%q<rspec>, ["~> 2.0.0"])
42
+ s.add_dependency(%q<fakeweb>, [">= 1.2"])
43
+ s.add_dependency(%q<rack>, [">= 1.0"])
44
+ s.add_dependency(%q<curb>, [">= 0.6"])
45
+ s.add_dependency(%q<excon>, ["~> 0.3.4"])
46
+ s.add_dependency(%q<i18n>, [">= 0.4.0"])
47
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
48
+ end
49
+ end