riakrest 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,9 @@ module RiakRest
16
16
  # already stored by Jiak. Schema designations only affect structured Jiak
17
17
  # interaction, not the data itself.
18
18
  #
19
+ # At this time, Riak does not support concurrent bucket access with different
20
+ # schemas, so the bucket interactions is semi-static.
21
+ #
19
22
  # The fields are kept as symbols or strings in four attribute arrays:
20
23
  # <code>allowed_fields</code>:: Allowed in Jiak interaction.
21
24
  # <code>required_fields</code>:: Required during Jiak interaction.
@@ -26,6 +29,13 @@ module RiakRest
26
29
  # not meaningful, including a symbol that "equals" a string. Duplicates
27
30
  # fields are ignored.
28
31
  #
32
+ # Riak supports wild cards in schemas. The wild card is specified using the
33
+ # constant JiakSchema::WILDCARD. The constant JiakSchema::WIDE_OPEN specifies
34
+ # a wide open schema with allowed_fields, read_mask, and write_mask all set
35
+ # to JiakSchema::WILDCARD, and required_fields set to an empty array. The
36
+ # wide open schema allows the least restricted interaction with Jiak server
37
+ # data. An initially created Riak bucket has the wide open schema setting.
38
+ #
29
39
  # ===Usage
30
40
  # <pre>
31
41
  # schema = JiakSchema.new([:foo,:bar])
@@ -42,6 +52,10 @@ module RiakRest
42
52
  # </pre>
43
53
  class JiakSchema
44
54
 
55
+ # Wild card constant.
56
+ WILDCARD = "*"
57
+ WILDCARD.freeze
58
+
45
59
  attr_accessor :allowed_fields, :required_fields, :read_mask, :write_mask
46
60
 
47
61
  # call-seq:
@@ -108,6 +122,16 @@ module RiakRest
108
122
  :read_mask => arg,
109
123
  :write_mask => arg
110
124
  }
125
+ when String
126
+ unless(arg.eql?(WILDCARD))
127
+ raise JiakSchemaException, "Initialize string can only be WILDCARD"
128
+ end
129
+ opts = {
130
+ :allowed_fields => WILDCARD,
131
+ :required_fields => [],
132
+ :read_mask => WILDCARD,
133
+ :write_mask => WILDCARD
134
+ }
111
135
  when nil
112
136
  arr = []
113
137
  opts = {
@@ -117,15 +141,20 @@ module RiakRest
117
141
  :write_mask => arr
118
142
  }
119
143
  else
120
- raise JiakSchemaException, "Initialize arg must be either hash or array"
144
+ raise JiakSchemaException, "Illegal initialize arg"
121
145
  end
122
-
146
+
147
+ # Dup to protect internal arrays from those passed into initialize
123
148
  @allowed_fields = opts[:allowed_fields].dup
124
149
  @required_fields = opts[:required_fields].dup
125
150
  @read_mask = opts[:read_mask].dup
126
151
  @write_mask = opts[:write_mask].dup
127
152
  end
128
153
 
154
+ # Wide open schema constant.
155
+ WIDE_OPEN = JiakSchema.new(WILDCARD)
156
+ WIDE_OPEN.freeze
157
+
129
158
  # call-seq:
130
159
  # JiakSchema.from_json(json) -> JiakSchema
131
160
  #
@@ -200,18 +229,20 @@ module RiakRest
200
229
  # allow(:f1,...,:fn) -> array
201
230
  # allow([:f1,...,:fn]) -> array
202
231
  #
203
- # Add to the allowed fields array.
232
+ # Add to the allowed fields array. Overwrites JiakSchema::WILDCARD array.
204
233
  #
205
234
  # Returns fields added to allowed fields.
206
235
  def allow(*fields)
207
- add_fields(@allowed_fields,"allow",fields)
236
+ added_fields = add_fields(@allowed_fields,"allow",fields)
237
+ @allowed_fields = added_fields if(@allowed_fields.eql?(WILDCARD))
238
+ added_fields
208
239
  end
209
240
 
210
241
  # :call-seq:
211
242
  # require(:f1,...,:fn) -> array
212
243
  # require([:f1,...,:fn]) -> array
213
244
  #
214
- # Add fields to the required fields array. Adds the fields to the allowed
245
+ # Add fields to the required fields array. Adds the fields to the allowed
215
246
  # fields as well.
216
247
  #
217
248
  # Returns fields added to required_fields.
@@ -226,12 +257,13 @@ module RiakRest
226
257
  # readable([:f1,...,:fn]) -> array
227
258
  #
228
259
  # Add fields to the read mask array. Adds the fields to the allowed
229
- # fields as well.
260
+ # fields as well. Overwrites JiakSchema::WILDCARD arrays.
230
261
  #
231
262
  # Returns fields added to read_mask
232
263
  def readable(*fields)
233
264
  added_fields = add_fields(@read_mask,"readable",fields)
234
265
  allow(*fields)
266
+ @read_mask = added_fields if(@read_mask.eql?(WILDCARD))
235
267
  added_fields
236
268
  end
237
269
 
@@ -240,12 +272,13 @@ module RiakRest
240
272
  # writable([:f1,...,:fn]) -> array
241
273
  #
242
274
  # Add fields to the write mask array. Adds the fields to the allowed
243
- # fields as well.
275
+ # fields as well. Overwrites JiakSchema::WILDCARD arrays.
244
276
  #
245
277
  # Returns fields added to write_mask
246
278
  def writable(*fields)
247
279
  added_fields = add_fields(@write_mask,"writable",fields)
248
280
  allow(*fields)
281
+ @write_mask = added_fields if(@write_mask.eql?(WILDCARD))
249
282
  added_fields
250
283
  end
251
284
 
@@ -254,7 +287,7 @@ module RiakRest
254
287
  # readwrite([:f1,...,:fn]) -> nil
255
288
  #
256
289
  # Add fields to the read and write mask arrays. Adds the fields to the
257
- # allowed fields as well.
290
+ # allowed fields as well. Overwrites JiakSchema::WILDCARD arrays.
258
291
  #
259
292
  # Returns nil.
260
293
  def readwrite(*fields)
@@ -269,7 +302,11 @@ module RiakRest
269
302
  def add_fields(arr,descr,fields)
270
303
  fields = fields[0] if(fields.size == 1 && fields[0].is_a?(Array))
271
304
  scrubbed = transform_fields(descr,fields)
272
- (scrubbed - arr).each {|f| arr << f}
305
+ if(arr.eql?(WILDCARD))
306
+ arr = scrubbed
307
+ else
308
+ (scrubbed - arr).each {|f| arr << f}
309
+ end
273
310
  end
274
311
  private :add_fields
275
312
 
@@ -317,58 +354,65 @@ module RiakRest
317
354
  # schema == other -> true or false
318
355
  #
319
356
  # Equality -- Two schemas are equal if they contain the same array elements
320
- # for all attributes, irrespective of order.
357
+ # for all attributes, regardless of order.
321
358
  def ==(other)
322
- (@allowed_fields.same_fields?(other.allowed_fields) &&
323
- @required_fields.same_fields?(other.required_fields) &&
324
- @read_mask.same_fields?(other.read_mask) &&
325
- @write_mask.same_fields?(other.write_mask)) rescue false
359
+ (compare_fields(@allowed_fields,other.allowed_fields) &&
360
+ compare_fields(@required_fields,other.required_fields) &&
361
+ compare_fields(@read_mask,other.read_mask) &&
362
+ compare_fields(@write_mask,other.write_mask)) rescue false
326
363
  end
327
364
 
328
365
  # call-seq:
329
366
  # schema.eql?(other) -> true or false
330
367
  #
331
368
  # Returns <code>true</code> if <code>other</code> is a JiakSchema with the
332
- # same array elements, irrespective of order.
369
+ # same array elements, regardless of order.
333
370
  def eql?(other)
334
371
  other.is_a?(JiakSchema) &&
335
- @allowed_fields.same_fields?(other.allowed_fields) &&
336
- @required_fields.same_fields?(other.required_fields) &&
337
- @read_mask.same_fields?(other.read_mask) &&
338
- @write_mask.same_fields?(other.write_mask)
372
+ compare_fields(@allowed_fields,other.allowed_fields) &&
373
+ compare_fields(@required_fields,other.required_fields) &&
374
+ compare_fields(@read_mask,other.read_mask) &&
375
+ compare_fields(@write_mask,other.write_mask)
376
+ end
377
+
378
+ def compare_fields(arg1,arg2)
379
+ if(arg1.is_a?(Array) && arg2.is_a?(Array))
380
+ arg1.same_fields?(arg2)
381
+ elsif(arg1.is_a?(String) && arg2.is_a?(String))
382
+ arg1.eql?(arg2)
383
+ else
384
+ false
385
+ end
339
386
  end
340
387
 
341
388
  def hash # :nodoc:
342
- @allowed_fields.name.hash + @required_fields.hash +
389
+ @allowed_fields.hash + @required_fields.hash +
343
390
  @read_mask.hash + @write_mask.hash
344
391
  end
345
392
 
346
393
  # String representation of this schema.
347
394
  def to_s
348
- 'allowed_fields="'+@allowed_fields.inspect+
349
- '",required_fields="'+@required_fields.inspect+
350
- '",read_mask="'+@read_mask.inspect+
351
- '",write_mask="'+@write_mask.inspect+'"'
395
+ af = "allowed_fields=#{@allowed_fields.inspect}"
396
+ rf = "required_fields=#{@required_fields.inspect}"
397
+ rm = "read_mask=#{@read_mask.inspect}"
398
+ wm = "write_mask=#{@write_mask.inspect}"
399
+ "#{af},#{rf},#{rm},#{wm}"
352
400
  end
353
401
 
354
402
  # Check for array of symbol or string elements.
355
403
  def transform_fields(desc,arr)
356
- if(arr.eql?("*"))
357
- raise(JiakSchemaException,
358
- "RiakRest does not support wildcard schemas at this time.")
359
- end
360
- unless arr.is_a?(Array)
361
- raise JiakSchemaException, "#{desc} must be an array"
362
- end
363
- arr.each do |field|
364
- unless(field.is_a?(String) || field.is_a?(Symbol))
365
- raise JiakSchemaException, "#{desc} must be strings or symbols"
404
+ if(arr.is_a?(Array))
405
+ arr.each do |field|
406
+ unless(field.is_a?(String) || field.is_a?(Symbol))
407
+ raise JiakSchemaException, "#{desc} must be strings or symbols"
408
+ end
366
409
  end
410
+ arr.map{|f| f.to_sym}.uniq
411
+ elsif(arr.eql?(WILDCARD))
412
+ arr
413
+ else
414
+ raise JiakSchemaException, "#{desc} must be an array or WILDCARD"
367
415
  end
368
- # unless arr.map{|f| f.to_s}.uniq.size == arr.size
369
- # raise JiakSchemaException, "#{desc} must have unique elements."
370
- # end
371
- arr.map{|f| f.to_sym}.uniq
372
416
  end
373
417
  private :transform_fields
374
418
 
@@ -35,15 +35,15 @@ module RiakRest
35
35
  module ClassMethods
36
36
 
37
37
  # :call-seq:
38
- # JiakServer.server(uri,opts={})
38
+ # JiakResource.server(uri,opts={})
39
39
  #
40
40
  # Set the URI for Jiak server interaction. Go through a proxy if proxy
41
41
  # option specified.
42
42
  #
43
- # Valid options:
44
- # <code>:proxy</code> Proxy server URI.
43
+ # =====Valid options:
44
+ # <code>:proxy</code> -- Proxy server URI.
45
45
  def server(uri,opts={})
46
- jiak.server = JiakClient.new(uri,opts)
46
+ jiak.client = JiakClient.new(uri,opts)
47
47
  jiak.uri = uri
48
48
  end
49
49
 
@@ -64,9 +64,11 @@ module RiakRest
64
64
  check_fields(fields)
65
65
  added_fields = jiak.data.readable(*fields)
66
66
  added_fields.each do |field|
67
- define_method("#{field}") do
68
- @jiak.data.send("#{field}")
69
- end
67
+ class_eval <<-EOM
68
+ def #{field}
69
+ @jiak.data.#{field}
70
+ end
71
+ EOM
70
72
  end
71
73
  nil
72
74
  end
@@ -80,10 +82,12 @@ module RiakRest
80
82
  check_fields(fields)
81
83
  added_fields = jiak.data.writable(*fields)
82
84
  added_fields.each do |field|
83
- define_method("#{field}=") do |val|
84
- @jiak.data.send("#{field}=",val)
85
- self.class.do_auto_update(self)
86
- end
85
+ class_eval <<-EOM
86
+ def #{field}=(val)
87
+ @jiak.data.#{field} = val
88
+ self.class.do_auto_update(self)
89
+ end
90
+ EOM
87
91
  end
88
92
  nil
89
93
  end
@@ -105,6 +109,10 @@ module RiakRest
105
109
  end
106
110
  private :check_fields
107
111
 
112
+ # :call-seq:
113
+ # keygen(&block)
114
+ #
115
+ # Specify the block for generating keys for a JiakResource instance.
108
116
  def keygen(&block)
109
117
  jiak.data.class_eval <<-EOS
110
118
  define_method(:keygen,&block)
@@ -114,22 +122,27 @@ module RiakRest
114
122
  # :call-seq:
115
123
  # JiakResource.params(opts={}) -> hash
116
124
  #
117
- # Default options for request parameters during Jiak interaction. Valid
118
- # options are:
119
- #
120
- # <code>:reads</code> :: The number of Riak nodes that must successfully read data.
121
- # <code>:writes</code> :: The number of Riak nodes that must successfully store data.
122
- # <code>:durable_writes</code> :: The number of Riak nodes (<code>< writes</code>) that must successfully store data in a durable manner.
123
- # <code>:waits</code> :: The number of Riak nodes that must reply the delete has occurred before success.
124
- #
125
- # Request parameters can be set at the JiakResource level using this
126
- # method, or at the individual call level. The order of precedence for
127
- # setting each parameter at the time of the Jiak interaction is
128
- # individual call -> JiakResource -> Riak cluster. In general the values
129
- # set on the Riak cluster should suffice and these parameters aren't
130
- # necessary for Jiak interaction.
125
+ # Default options for request parameters during Jiak interaction.
126
+ #
127
+ # =====Valid options
128
+ # <code>:reads</code>:: Minimum number of responding nodes for successful reads.
129
+ # <code>:writes</code>:: Minimum number of responding nodes for successful writes. Writes can be buffered for performance.
130
+ # <code>:durable_writes</code>:: Minimum number of resonding nodes that must perform a durable write to the persistence layer.
131
+ # <code>:deletes</code>:: Minimum number of responding nodes for successful delete.
132
+ #
133
+ # The configuration of a Riak cluster includes server setting for
134
+ # <code>writes, durable_writes, reads,</code> and <code>deletes</code>
135
+ # parameters. None of these parameter are required by RiakRest, and their
136
+ # use within RiakRest is to override the Riak cluster settings, either at
137
+ # the JiakResource level or the individual request level.
138
+ #
139
+ # Settings passed to individual <code>get, put, post, update,
140
+ # refresh,</code> and <code>delete</code> requests take precendence over
141
+ # the setting maintained by a JiakResource. Any parameter not set in
142
+ # JiakResource or on an individual request will default to the values
143
+ # set in the Riak cluster.
131
144
  def params(opts={})
132
- jiak.server.params = opts
145
+ jiak.client.params = opts
133
146
  end
134
147
 
135
148
  # :call-seq:
@@ -205,25 +218,25 @@ module RiakRest
205
218
  jiak.data.schema
206
219
  end
207
220
 
208
- # JiakResource.point_of_view -> JiakSchema
221
+ # :call-seq:
222
+ # JiakResource.push_schema -> nil
209
223
  #
210
- # Ready the Jiak server point-of-view to accept structured interaction
211
- # with a JiakResource. Returns the schema set on the Jiak server.
212
- def point_of_view
213
- jiak.server.set_schema(jiak.bucket)
214
- jiak.bucket.schema
224
+ # Push schema to the Jiak server. If no schema is provided, pushes the
225
+ # schema associated with the JiakResource.
226
+ def push_schema(schema=nil)
227
+ schema ||= jiak.bucket.schema
228
+ jiak.client.set_schema(jiak.bucket.name,schema)
215
229
  end
216
- alias :pov :point_of_view
217
230
 
218
231
  # :call-seq:
219
- # JiakResource.point_of_view? -> true or false
232
+ # JiakResource.server_schema? -> true or false
220
233
  #
221
- # Determine if the point-of-view on the Jiak server is that of this
222
- # JiakResource.
223
- def point_of_view?
224
- jiak.server.schema(jiak.bucket).eql? jiak.bucket.schema
234
+ # Determine if a schema is that set on the Jiak server. If no schema is
235
+ # provided, use the schema associated with the JiakResource.
236
+ def server_schema?(schema=nil)
237
+ schema ||= jiak.bucket.schema
238
+ jiak.client.schema(jiak.bucket).eql? schema
225
239
  end
226
- alias :pov? :point_of_view?
227
240
 
228
241
  # :call-seq:
229
242
  # JiakResource.keys -> array
@@ -232,17 +245,18 @@ module RiakRest
232
245
  # updated asynchronously on a Riak cluster the returned array can be out
233
246
  # of synch immediately after new puts or deletes.
234
247
  def keys
235
- jiak.server.keys(jiak.bucket)
248
+ jiak.client.keys(jiak.bucket)
236
249
  end
237
250
 
238
251
  # :call-seq:
239
252
  # JiakResource.put(JiakResource,opts={}) -> JiakResource
240
253
  #
241
- # Put a JiakResource on the Jiak server. Valid options are:
254
+ # Put a JiakResource on the Jiak server.
242
255
  #
243
- # <code>:writes</code> :: The number of Riak nodes that must successfully store the data.
244
- # <code>:durable_writes</code> :: The number of Riak nodes (<code>< writes</code>) that must successfully store the data in a durable manner.
245
- # <code>:reads</code> :: The number of Riak nodes that must successfully read data being returned.
256
+ # =====Valid options:
257
+ # <code>:writes</code>
258
+ # <code>:durable_writes</code>
259
+ # <code>:reads</code>
246
260
  #
247
261
  # If any of the request parameters <code>:writes, :durable_writes,
248
262
  # :reads</code> are not set, each first defaults to the value set for the
@@ -250,7 +264,7 @@ module RiakRest
250
264
  # general the values set on the Riak cluster should suffice.
251
265
  def put(resource,opts={})
252
266
  opts[:return] = :object
253
- resource.jiak.object = jiak.server.store(resource.jiak.object,opts)
267
+ resource.jiak.object = jiak.client.store(resource.jiak.object,opts)
254
268
  resource.jiak_convenience
255
269
  resource
256
270
  end
@@ -259,8 +273,9 @@ module RiakRest
259
273
  # JiakResource.post(JiakResource,opts={}) -> JiakResource
260
274
  #
261
275
  # Put a JiakResource on the Jiak server with a guard to ensure the
262
- # resource has not been previously stored. See JiakResource#put for
263
- # options.
276
+ # resource has not been previously stored.
277
+ #
278
+ # See JiakResource#put for options.
264
279
  def post(resource,opts={})
265
280
  unless(resource.local?)
266
281
  raise JiakResourceException, "Resource already initially stored"
@@ -272,7 +287,9 @@ module RiakRest
272
287
  # JiakResource.update(JiakResource,opts={}) -> JiakResource
273
288
  #
274
289
  # Updates a JiakResource on the Jiak server with a guard to ensure the
275
- # resource has been previously stored. See JiakResource#put for options.
290
+ # resource has been previously stored.
291
+ #
292
+ # See JiakResource#put for options.
276
293
  def update(resource,opts={})
277
294
  if(resource.local?)
278
295
  raise JiakResourceException, "Resource not previously stored"
@@ -283,41 +300,39 @@ module RiakRest
283
300
  # :call-seq:
284
301
  # JiakResource.get(key,opts={}) -> JiakResource
285
302
  #
286
- # Get a JiakResource on the Jiak server by the specified key. Valid
287
- # options are:
303
+ # Get a JiakResource on the Jiak server by the specified key.
288
304
  #
289
- # <code>:reads</code> --- The number of Riak nodes that must successfully
290
- # reply with the data. If not set, defaults first to the value set for the
291
- # JiakResource class, then to the value set on the Riak cluster.
305
+ # =====Valid options:
306
+ # <code>:reads</code> --- See JiakResource#new
292
307
  #
293
308
  # Raise JiakResourceNotFound if no resource exists on the Jiak server for
294
309
  # the key.
295
310
  def get(key,opts={})
296
- new(jiak.server.get(jiak.bucket,key,opts))
311
+ new(jiak.client.get(jiak.bucket,key,opts))
297
312
  end
298
313
 
299
314
  # :call-seq:
300
315
  # JiakResource.refresh(resource,opts={}) -> JiakResource
301
316
  #
302
317
  # Updates a JiakResource with the data on the Jiak server. The current
303
- # data of the JiakResource is overwritten, so use with caution. See
304
- # JiakResource.get for options.
318
+ # data of the JiakResource is overwritten, so use with caution.
319
+ #
320
+ # See JiakResource#put for options.
305
321
  def refresh(resource,opts={})
306
322
  resource.jiak.object = get(resource.jiak.key,opts).jiak.object
323
+ resource.jiak_convenience
307
324
  end
308
325
 
309
326
  # :call-seq:
310
327
  # JiakResource.delete(resource,opts={}) -> true or false
311
328
  #
312
329
  # Delete the JiakResource store on the Jiak server by the specified
313
- # key. Valid options are:
330
+ # key.
314
331
  #
315
- # <code>:waits</code> --- The number of Riak nodes that must reply the
316
- # delete has occurred before success. If not set, defaults first to the
317
- # value set for the JiakResource, then to the value set on the Riak
318
- # cluster. In general the values set on the Riak cluster should suffice.
332
+ # =====Valid options:
333
+ # <code>:deletes</code> --- See JiakResource#new
319
334
  def delete(resource,opts={})
320
- jiak.server.delete(jiak.bucket,resource.jiak.object.key,opts)
335
+ jiak.client.delete(jiak.bucket,resource.jiak.object.key,opts)
321
336
  end
322
337
 
323
338
  # :call-seq:
@@ -405,7 +420,7 @@ module RiakRest
405
420
  end
406
421
  end
407
422
  links = links[0] if links.size == 1
408
- jiak.server.walk(from.jiak.object.bucket, from.jiak.object.key, links,
423
+ jiak.client.walk(from.jiak.object.bucket, from.jiak.object.key, links,
409
424
  last_klass.jiak.bucket.data_class).map do |jobj|
410
425
  last_klass.new(jobj)
411
426
  end
@@ -417,12 +432,7 @@ module RiakRest
417
432
  #
418
433
  # Determine if a resource exists on the Jiak server for a key.
419
434
  def exist?(key)
420
- begin
421
- get(key)
422
- true
423
- rescue JiakResourceNotFound
424
- false
425
- end
435
+ jiak.client.exist?(jiak.bucket,key)
426
436
  end
427
437
 
428
438
  # :call-seq:
@@ -448,7 +458,7 @@ module RiakRest
448
458
  def jiak # :nodoc:
449
459
  @jiak
450
460
  end
451
- @jiak = Struct.new(:server,:uri,:group,:data,:bucket,
461
+ @jiak = Struct.new(:client,:uri,:group,:data,:bucket,
452
462
  :auto_post,:auto_update).new
453
463
  @jiak.data = JiakDataFields.create
454
464
  @jiak.group = self.name.split('::').last.downcase
@@ -463,7 +473,7 @@ module RiakRest
463
473
  # Instance methods
464
474
  # ----------------------------------------------------------------------
465
475
 
466
- attr_accessor :jiak # :nodoc:
476
+ attr_reader :jiak # :nodoc:
467
477
 
468
478
  # :call-seq:
469
479
  # JiakResource.new(*args) -> JiakResource
@@ -522,7 +532,8 @@ module RiakRest
522
532
  # :call-seq:
523
533
  # auto_update? -> true, false, or nil
524
534
  #
525
- # Get current auto_update setting. See JiakResource#auto_update for settings.
535
+ # Get current auto_update setting. See JiakResource#auto_update for
536
+ # settings.
526
537
  def auto_update?
527
538
  @jiak.auto_update
528
539
  end
@@ -639,7 +650,7 @@ module RiakRest
639
650
  # :call-seq:
640
651
  # jiak_resource == other -> true or false
641
652
  #
642
- # Equality -- Two JiakResources are equal if they wrap the same data.
653
+ # Equality -- Two JiakResources are equal if they wrap the same Jiak data.
643
654
  def ==(other)
644
655
  (@jiak.object == other.jiak.object) rescue false
645
656
  end
data/lib/riakrest.rb CHANGED
@@ -2,16 +2,18 @@
2
2
  begin
3
3
  require 'json'
4
4
  rescue LoadError
5
- raise "RiakRest requires json for REST JSON messaging."
5
+ puts "\nRiakRest requires json for REST JSON messaging."
6
+ puts " Install with: gem install json"
7
+ puts
8
+ exit
6
9
  end
7
10
 
8
11
  begin
9
12
  require 'restclient'
10
13
  rescue LoadError
11
- raise <<EOM
12
- RiakRest requires the restclient gem for making REST calls.
13
- gem install rest-client
14
- EOM
14
+ puts "\nRiakRest requires the restclient gem for making REST calls."
15
+ puts " Install with: gem install rest-client"
16
+ exit
15
17
  end
16
18
 
17
19
  require 'uri'
@@ -59,12 +61,17 @@ module RiakRest
59
61
  VERSION = IO.read(version_file).chomp
60
62
 
61
63
  # Convenience method for checking validity of method options. If any of the
62
- # options in opt are not in valid, raise the exception with the invalid
64
+ # options in opt are not in valid, raise the exception listing the invalid
63
65
  # options in the message.
64
66
  def check_opts(opts,valid,exception) # :nodoc:
65
- err = opts.select {|k,v| !valid.include?(k)}
66
- unless err.empty?
67
- raise exception, "unrecognized options: #{err.keys}"
67
+ unless(opts.empty?)
68
+ err = opts.inject({}) do |h,(k,v)|
69
+ h[k] = v unless(valid.include?(k))
70
+ h
71
+ end
72
+ unless err.empty?
73
+ raise exception, "unrecognized options: #{err.keys}"
74
+ end
68
75
  end
69
76
  opts
70
77
  end
@@ -52,6 +52,9 @@ describe "JiakBucket" do
52
52
 
53
53
  bad_data_class = lambda {@bucket.data_class = Hash}
54
54
  bad_data_class.should raise_error(JiakBucketException,/JiakData/)
55
+
56
+ nil_data_class = lambda {JiakBucket.new(@name,nil)}
57
+ nil_data_class.should raise_error(JiakBucketException,/JiakData/)
55
58
  end
56
59
 
57
60
  it "should provide the schema for the data class" do