riakpb 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -88,6 +88,38 @@ This is a work in progress and I am current improving the rspec and the document
88
88
  => #<#Riak::RiakContent value={"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="264RmLHrCK89zvhtq4n6Fj", links=[], last_mod=1276389859, last_mod_usecs=810556, usermeta={}>
89
89
  >>
90
90
 
91
+ === Junkshot: (Siblings)
92
+
93
+ >> client = Riak::Client.new
94
+ => #<Riak::Client:0x00000100d2b998 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
95
+ >> bucket = client["goog2"]
96
+ => #<Riak::Bucket name=goog2, props={n_val=>3, allow_mult=false}>
97
+ >> bucket.allow_mult = true
98
+ => true
99
+ >> client.junkshot "goog2", "2010-04-12", {:links => {"tomorrow" => ["goog2", "2010-04-13"]}}
100
+ => content {
101
+ value: ""
102
+ vtag: "3jfZii80dgtSPYbZ6CL1PU"
103
+ links {
104
+ bucket: "goog2"
105
+ key: "2010-04-13"
106
+ tag: "tomorrow"
107
+ }
108
+ last_mod: 1276715503
109
+ last_mod_usecs: 980712
110
+ }
111
+ content {
112
+ value: "{\"Date\":\"2010-04-12\",\"Open\":\"567.35\",\"High\":\"574.00\",\"Low\":\"566.22\",\"Close\":\"572.73\",\"Volume\":\"2352400\",\"Adj Close\":\"572.73\"}"
113
+ content_type: "application/json"
114
+ vtag: "2UplDRmlJaxS1rhn0GNgqN"
115
+ last_mod: 1276651742
116
+ last_mod_usecs: 417836
117
+ }
118
+ vclock: "k\xCEa``\xE0\xCA`\xCA\x05R,\xCC_s\xBEd0%2\xE5\xB12<^\xDAq\x94\x0F&|`\xF6n\xA00#P\xF8\xDE\x92\x1E\x980[s\x12S\x1F\xCBU\xA8\xC4\xA4\xC9\xBDp\xF5\xEC<\x8B\x0F`\n\x03\xD5\xB3\xE9x\x9C\x85Jh\xCE@\xA8g\xCE\xB00\xC3\x14\x06\xAAg\xBF\xB9\xE5\x14TBq\x0EB=\xD3u\xE7r,\xC2\x8C\xAB\xDC\xEFA\x85\xDF\xCFE6\x865.'\bY\"\v\x00"
119
+
120
+ >>
121
+
122
+
91
123
  === MapReduce:
92
124
 
93
125
  I'm working on ways to simplify M/R requests. It works the same as in ripple. Largely because it's ripped off from it, with very few changes (so far).
data/lib/riak/bucket.rb CHANGED
@@ -29,11 +29,11 @@ module Riak
29
29
  raise ArgumentError, t("client_type", :client => client.inspect) unless client.is_a?(Client)
30
30
  raise ArgumentError, t("string_type", :string => name.inspect) unless name.is_a?(String)
31
31
 
32
- @client = client
33
- @name = name
34
- @n_val = options[:n_val] || nil
35
- @allow_mult = options[:allow_mult] || nil
36
- @key_cache = Hash.new{|k,v| k[v] = Riak::Key.new(self, v)}
32
+ @client = client
33
+ @name = name
34
+ self.n_val ||= options[:n_val]
35
+ self.allow_mult ||= options[:allow_mult]
36
+ @key_cache = Hash.new{|k,v| k[v] = Riak::Key.new(self, v)}
37
37
  end
38
38
 
39
39
  # Load information for the bucket from a response given by the {Riak::Client::HTTPBackend}.
@@ -42,12 +42,13 @@ module Riak
42
42
  # @return [Bucket] self
43
43
  # @see Client#bucket
44
44
  def load(response)
45
- raise ArgumentError, t("response_type") unless response.is_a?(Riak::RpbGetBucketResp)
45
+ if response.is_a?(Riak::RpbGetBucketResp)
46
+ @n_val = response.props.n_val
47
+ @allow_mult = response.props.allow_mult
46
48
 
47
- self.n_val = response.props.n_val
48
- self.allow_mult = response.props.allow_mult
49
-
50
- return(self)
49
+ return(self)
50
+ end
51
+ raise ArgumentError, t("response_type")
51
52
  end
52
53
 
53
54
  # Accesses or retrieves a list of keys in this bucket. Needs to have expiration / cacheing, though not now.
@@ -86,7 +87,7 @@ module Riak
86
87
  # @return [Riak::Key] the object
87
88
  def key!(key, r=nil)
88
89
  raise ArgumentError, t("string_invalid", :string => key) unless key.is_a?(String)
89
- raise ArgumentError, t("fixnum_invalid", :num => r) unless r.is_a?(Fixnum)
90
+ raise ArgumentError, t("fixnum_invalid", :num => r) unless r.is_a?(Fixnum) or r.nil?
90
91
 
91
92
  response = @client.get_request @name, key, r
92
93
 
@@ -113,6 +114,22 @@ module Riak
113
114
  @client.put_request(options)
114
115
  end
115
116
 
117
+ def junkshot(key, params)
118
+ raise RuntimeError.new t('siblings_disallowed') unless @allow_mult == true
119
+
120
+ params[:links] = parse_links(params[:links]) if params.has_key?(:links)
121
+ params[:usermeta] = parse_links(params[:usermeta]) if params.has_key?(:usermeta)
122
+
123
+ options = params.slice :return_body, :w, :dw
124
+ content = params.slice :value, :content_type, :charset, :content_encoding, :links, :usermeta
125
+
126
+ key = key.name if key.is_a?(Riak::Key)
127
+ options[:key] = key
128
+ options[:content] = Riak::RpbContent.new(content)
129
+
130
+ self.store(options)
131
+ end
132
+
116
133
  # Deletes a key from the bucket
117
134
  # @param [String] key the key to delete
118
135
  # @param [Hash] options quorum options
@@ -144,9 +161,15 @@ module Riak
144
161
  # Set the allow_mult property. *NOTE* This will result in a PUT request to Riak.
145
162
  # @param [true, false] value whether the bucket should allow siblings
146
163
  def allow_mult=(value)
147
- return(@allow_mult = value) if value.is_a?(TrueClass) or value.is_a?(FalseClass)
148
-
149
- raise ArgumentError, t("boolean_type")
164
+ case value
165
+ when true, false
166
+ @client.set_bucket(self.name, {:n_val => @n_val, :allow_mult => value})
167
+ return(@allow_mult = value)
168
+ when nil, ''
169
+ return(@allow_mult = nil)
170
+ else
171
+ raise ArgumentError, t("boolean_type")
172
+ end
150
173
  end
151
174
 
152
175
  # @return [Fixnum] the N value, or number of replicas for this bucket
@@ -158,9 +181,15 @@ module Riak
158
181
  # Saving this value after the bucket has objects stored in it may have unpredictable results.
159
182
  # @param [Fixnum] value the number of replicas the bucket should keep of each object
160
183
  def n_val=(value)
161
- raise ArgumentError, t("fixnum_type", :value => value) unless value.is_a?(Fixnum)
162
-
163
- @n_val = value
184
+ case value
185
+ when Fixnum
186
+ @client.set_bucket(self.name, {:n_val => value, :allow_mult => @allow_mult})
187
+ return(@n_val = value)
188
+ when nil, ''
189
+ return(@n_val = nil)
190
+ else
191
+ raise ArgumentError, t("fixnum_type", :value => value)
192
+ end
164
193
  end
165
194
 
166
195
  # @return [String] a representation suitable for IRB and debugging output
@@ -173,5 +202,30 @@ module Riak
173
202
  "#<Riak::Bucket name=#{@name}, props={n_val=>#{@n_val}, allow_mult=#{@allow_mult}}, keys=#{keys.inspect}>"
174
203
  end
175
204
 
205
+ private
206
+ def parse_links(link_params)
207
+ rpb_links = []
208
+
209
+ link_params.each do |tag, links|
210
+ pb_link = Riak::RpbLink.new
211
+ pb_link.tag = tag
212
+ pb_link.bucket = links[0]
213
+ pb_link.key = links[1]
214
+ rpb_links << pb_link
215
+ end
216
+ return(rpb_links)
217
+ end # parse_links
218
+
219
+ def parse_meta(meta_params)
220
+ rpb_meta = []
221
+
222
+ meta_params.each do |k,v|
223
+ pb_meta = Riak::RpbPair.new
224
+ pb_meta.key = k
225
+ pb_meta.value = v
226
+ rpb_meta << pb_meta
227
+ end
228
+ return(rpb_meta)
229
+ end
176
230
  end
177
231
  end
@@ -19,10 +19,12 @@ module Riak
19
19
  attr_reader :req_message, :response, :resp_message_codes, :resp_message, :status
20
20
 
21
21
  # Establishes a Client ID with the Riak node, for the life of the RPC connection.
22
- # @param [Client] the Riak::Client object in which this Rpc instance lives
23
- def initialize(client)
22
+ # @param [Client] client the Riak::Client object in which this Rpc instance lives
23
+ # @param [Fixnum] limit the max size of an individual TCPSocket receive call. Need to fix, later.
24
+ def initialize(client, limit=RECV_LIMIT)
24
25
  @status = false
25
26
  @client = client
27
+ @limit = limit
26
28
  @client_id = request(Util::MessageCode::GET_CLIENT_ID_REQUEST).client_id
27
29
  @set_client_id = Riak::RpbSetClientIdReq.new(:client_id => @client_id)
28
30
 
@@ -65,7 +67,7 @@ module Riak
65
67
  @set_client_id.serialize_to_string)
66
68
 
67
69
  socket.send(@set_c_id_req, 0)
68
- set_c_id_resp = socket.recv(RECV_LIMIT)
70
+ set_c_id_resp = socket.recv(@limit)
69
71
 
70
72
  resp_code, resp_msg = decode_message(set_c_id_resp)
71
73
 
@@ -84,10 +86,14 @@ module Riak
84
86
 
85
87
  with_socket do |socket|
86
88
  begin
87
- @req_message = assemble_request mc, (pb_msg.serialize_to_string rescue '')
89
+ begin
90
+ @req_message = assemble_request mc, pb_msg.serialize_to_string
91
+ rescue NoMethodError
92
+ @req_message = assemble_request mc
93
+ end
88
94
 
89
95
  socket.send(@req_message, 0)
90
- self.response = socket.recv(RECV_LIMIT)
96
+ self.response = socket.recv(@limit)
91
97
 
92
98
  end while(false == (@response.done rescue true))
93
99
  end # with_socket
data/lib/riak/client.rb CHANGED
@@ -99,17 +99,48 @@ module Riak
99
99
  # I need bucket! Bring me bucket! (Retrieves a bucket from Riak. Eating disorder not included.)
100
100
  # @param [String] bucket the bucket to retrieve
101
101
  # @return [Bucket] the requested bucket
102
- def bring_me_bucket(bucket)
102
+ def bucket(bucket)
103
+ return(@bucket_cache[bucket]) if @bucket_cache.has_key?(bucket)
104
+ bring_me_bucket!(bucket)
105
+ end
106
+ alias :[] :bucket
107
+ alias :bring_me_bucket :bucket
108
+
109
+ # I need bucket! Bring me bucket! (Retrieves a bucket from Riak, even if it's already been retrieved.)
110
+ # @param [String] bucket the bucket to retrieve
111
+ # @return [Bucket] the requested bucket
112
+ def bucket!(bucket)
103
113
  request = Riak::RpbGetBucketReq.new(:bucket => bucket)
104
114
  response = rpc.request(
105
115
  Util::MessageCode::GET_BUCKET_REQUEST,
106
116
  request
107
117
  )
108
-
109
118
  @bucket_cache[bucket].load(response)
110
119
  end
111
- alias :[] :bring_me_bucket
112
- alias :bucket :bring_me_bucket
120
+ alias :bring_me_bucket! :bucket!
121
+
122
+ # Set the properties for a given bucket, and then reload it.
123
+ # @param [String] bucket the bucket name in which props will be set
124
+ # @param [RpbBucketProps, Hash] props the properties to be set within the given bucket
125
+ # @return [TrueClass, FalseClass] whether or not the operation was successful
126
+ def set_bucket(bucket, props)
127
+ props = Riak::RpbBucketProps.new(props) if props.is_a?(Hash)
128
+
129
+ raise TypeError.new t('invalid_props') unless props.is_a?(Riak::RpbBucketProps)
130
+
131
+ begin
132
+ request = Riak::RpbSetBucketReq.new(:bucket => bucket, :props => props)
133
+ response = rpc.request(
134
+ Util::MessageCode::SET_BUCKET_REQUEST,
135
+ request
136
+ )
137
+ self.bucket!(bucket)
138
+
139
+ return(true)
140
+ rescue FailedRequest
141
+ return(false)
142
+ end
143
+ end
113
144
 
114
145
  # Retrieves a key, using RpbGetReq, from within a given bucket, from Riak.
115
146
  # @param [String] bucket the bucket from which to retrieve the key
@@ -144,7 +175,6 @@ module Riak
144
175
  options[:return_body] ||= true
145
176
 
146
177
  request = Riak::RpbPutReq.new(options)
147
-
148
178
  response = rpc.request(
149
179
  Util::MessageCode::PUT_REQUEST,
150
180
  request
@@ -204,7 +234,6 @@ module Riak
204
234
  # @raise [ReturnRespError] if the message response does not correlate with the message requested
205
235
  # @return [Hash] Mapping of the buckets (String) to their keys (Array of Strings)
206
236
  def keys_in(bucket)
207
-
208
237
  list_keys_request = RpbListKeysReq.new(:bucket => bucket)
209
238
 
210
239
  response = rpc.request Util::MessageCode::LIST_KEYS_REQUEST, list_keys_request
@@ -217,6 +246,37 @@ module Riak
217
246
  # "#<Client >"
218
247
  # end
219
248
 
249
+ # Junkshot lets you throw a lot of data at riak, which will then need to be reconciled later
250
+ # @overload junkshot(bucket, key, params)
251
+ # @param [String] bucket the name of the bucket
252
+ # @param [String] key the name of the key
253
+ # @param [Hash] params the parameters that are to be updated (Needs fixin')
254
+ # @overload junkshot(key, params)
255
+ # @param [Key] key the Key instance to be junkshotted
256
+ # @param [Hash] params the parameters that are to be updated (Needs fixin')
257
+ # @return [String, Key] dependent upon whether :return_body is set to true or false
258
+ def junkshot(*params)
259
+ params = params.dup.flatten
260
+ case params.size
261
+ when 3
262
+ bucket = params[0]
263
+ key = params[1]
264
+ params = params[2]
265
+ when 2
266
+ begin
267
+ key = params[0]
268
+ bucket = key.bucket
269
+ key = key.name
270
+ rescue NoMethodError
271
+ raise TypeError.new t('invalid_key')
272
+ end
273
+ params = params[1]
274
+ end
275
+ self.bucket!(bucket).junkshot(key, params)
276
+ end
277
+ alias :stuff :junkshot
278
+ alias :jk :junkshot
279
+
220
280
  private
221
281
  def b64encode(n)
222
282
  Base64.encode64([n].pack("N")).chomp
@@ -343,7 +343,7 @@ module Riak
343
343
  end
344
344
  class RpbContent < ::Protobuf::Message
345
345
  defined_in __FILE__
346
- required :bytes, :value, 1
346
+ optional :bytes, :value, 1
347
347
  optional :bytes, :content_type, 2
348
348
  optional :bytes, :charset, 3
349
349
  optional :bytes, :content_encoding, 4
data/lib/riak/key.rb CHANGED
@@ -46,7 +46,7 @@ module Riak
46
46
 
47
47
  if response.has_field?(:content)
48
48
  self.content = response.content
49
- elsif @contents.empty?
49
+ elsif @contents.blank?
50
50
  @contents[:new]
51
51
  end
52
52
 
@@ -79,7 +79,7 @@ module Riak
79
79
  # Indicates whether or not the Key is empty
80
80
  # @return [Boolean] true or false, whether or not the vclock/content is empty
81
81
  def empty?
82
- return(true) if @vclock.empty? && (@contents.nil? || @contents.empty?)
82
+ return(true) if @vclock.blank? && @contents.nil?
83
83
  return(false)
84
84
  end
85
85
 
@@ -4,7 +4,8 @@ en:
4
4
  string_type: "invalid_argument {{string}} is not a String"
5
5
  loading_bucket: "while loading bucket '{{name}}'"
6
6
  invalid_bucket: "the specified bucket is invalid"
7
- invalid_key: "the specified key does not exist"
7
+ invalid_key: "the specified key is invalid or does not exist"
8
+ siblings_disallowed: "the specified bucket does not allow siblings. Set allow_mult in props to do this."
8
9
  value_empty: "a value must be set in order to serialize into a protocol buffer"
9
10
  failed_request: "Expected message code {{expected}} from Riak but received {{actual}}. {{output}}"
10
11
  decode_error: "Riak reported a message length of {{expected}} but length was {{actual}}. {{output}}"
@@ -138,6 +138,7 @@ module Riak
138
138
  end
139
139
  end # tags.each do |tag, link|
140
140
  end
141
+ alias :link :link_key
141
142
 
142
143
  # Set the links to other Key in riak.
143
144
  # @param [RpbGetResp, RpbPutResp] contains the tag/bucket/key of a given link
@@ -193,8 +194,8 @@ module Riak
193
194
  rpb_content.charset = @charset unless @charset.nil? # || @charset.empty?
194
195
  rpb_content.content_encoding = @content_encoding unless @content_encoding.nil? # || @content_encoding.empty?
195
196
  rpb_content.vtag = @vtag unless @vtag.nil?
196
- rpb_content.links = rpb_links unless rpb_links.empty?
197
- rpb_content.usermeta = usermeta unless usermeta.empty?
197
+ rpb_content.links = rpb_links unless rpb_links.nil?
198
+ rpb_content.usermeta = usermeta unless usermeta.nil?
198
199
 
199
200
  return(rpb_content)
200
201
  end
data/lib/riak.rb CHANGED
@@ -9,7 +9,7 @@ require 'base64'
9
9
  require 'riak/client_pb'
10
10
 
11
11
  module Riak
12
- VERSION = '0.1.3'
12
+ VERSION = '0.1.4'
13
13
 
14
14
  # Domain objects
15
15
  autoload :I18n, 'riak/i18n'
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 3
9
- version: 0.1.3
8
+ - 4
9
+ version: 0.1.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Scott Gonyea
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-14 00:00:00 -07:00
17
+ date: 2010-06-16 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency