Module: Blodsband::Riak::Response

Defined in:
lib/blodsband/riak/response.rb

Overview

The semi magical class encapsulating responses from Riak. Probably never constructed by API users.

Will mostly add the following fields to any object including it:

:status an Integer defining the status of the response. 300 means siblings, for example.
:links a Hash<String, Array<String>> with riaktags pointing to bucket/key pairs for the links.
:vclock the vector clock for the fetched value.
:last_modified when the document was last modified in Riak.
:key the key the document was found under (when applicable)
:bucket the name of the bucket the document was found in (when applicable)
:meta a Hash<String, String> with Riak meta keys pointing to Riak meta values for the document.

Defined Under Namespace

Modules: ClassMethods, InstanceMethods

Class Method Summary collapse

Class Method Details

.construct(status, headers, body, options = {}) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/blodsband/riak/response.rb', line 20

def self.construct(status, headers, body, options = {})
  rval = Yajl::Parser.parse(body)
  class << rval
    include Response
  end
  rval.apply(status, headers, options[:bucket], options[:key])
  rval
end

.included(base) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/blodsband/riak/response.rb', line 112

def self.included(base)
  unless base.include?(InstanceMethods)
    base.class_eval do
      attr_reader :status
      attr_reader :links
      attr_reader :vclock
      attr_reader :last_modified
      attr_reader :key
      attr_reader :bucket
      attr_reader :meta
      include InstanceMethods
    end
    base.extend(ClassMethods)
  end
end


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/blodsband/riak/response.rb', line 75

def self.inject_links(previous_links, document, links, responses)
  previous_links << links.shift
  response = responses.shift
  if document.is_a?(Hash)
    document[previous_links.join("->")] = response
  elsif document.respond_to?(:<<)
    document << response
  else
    document = [document, response]
  end
  if links.size > 0
    document = inject_links(previous_links, document, links, responses)
  end
  document
end

.parse(item, options = {}) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/blodsband/riak/response.rb', line 100

def self.parse(item, options = {})
  if item.is_a?(EM::Synchrony::Multi)
    if item.responses[:errback].empty?
      parse_callbacks(item, options)
    else
      raise Multi::Error.new(item)
    end
  else
    raise "Unparseable item #{item.inspect}"
  end
end

.parse_callbacks(multi, options = {}) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/blodsband/riak/response.rb', line 91

def self.parse_callbacks(multi, options = {})
  resp = parse_response(multi.responses[:callback][:resp], options)
  link_chains = options.delete(:links) || []
  link_chains.each do |chain|
    inject_links([], resp, chain, parse_response(multi.responses[:callback][chain]))
  end
  resp
end

.parse_multipart(part, options = {}) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/blodsband/riak/response.rb', line 29

def self.parse_multipart(part, options = {})
  if part["Content-Type"] =~ /multipart\/mixed/ || (part.respond_to?(:multipart?) && part.multipart?)
    part.parts.collect do |inner_part|
      parse_multipart(inner_part)
    end
  else
    construct(200, part, part.body.to_s, options)
  end
end

.parse_multipart_response(http, options = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/blodsband/riak/response.rb', line 39

def self.parse_multipart_response(http, options = {})
  mailbody = ""
  http.response_header.each do |k,v|
    mailbody += "#{k.gsub(/_/, "-")}: #{v}\n"
  end
  mailbody += http.response
  mail = Mail.new(mailbody)
  mail.parts.collect do |part|
    parse_multipart(part, options)
  end
end

.parse_response(http, options = {}) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/blodsband/riak/response.rb', line 51

def self.parse_response(http, options = {})
  return nil if http.nil?
  return nil if http.response_header.status == 404
  if (http.response_header.status == 200 || 
      http.response_header.status == 204 || 
      (http.response_header.status == 300 && http.response_header["Content-Type"] =~ /multipart\/mixed/))
    if http.response_header["Content-Type"] =~ /multipart\/mixed/
      rval = parse_multipart_response(http, options)
      class << rval
        include Response
      end
      rval.apply(http.response_header.status, http.response_header, options[:bucket], options[:key])
      rval
    else
      construct(http.response_header.status,
                http.response_header,
                http.response,
                options)
    end
  else
    raise Blodsband::Error.new(http)
  end
end