riakrest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +41 -0
  3. data/PostInstall.txt +2 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +24 -0
  6. data/examples/auto_update_data.rb +50 -0
  7. data/examples/auto_update_links.rb +48 -0
  8. data/examples/basic_client.rb +33 -0
  9. data/examples/basic_resource.rb +34 -0
  10. data/examples/json_data_resource.rb +32 -0
  11. data/examples/linked_resource.rb +113 -0
  12. data/examples/multiple_resources.rb +43 -0
  13. data/lib/riakrest/core/exceptions.rb +73 -0
  14. data/lib/riakrest/core/jiak_bucket.rb +146 -0
  15. data/lib/riakrest/core/jiak_client.rb +316 -0
  16. data/lib/riakrest/core/jiak_data.rb +265 -0
  17. data/lib/riakrest/core/jiak_link.rb +131 -0
  18. data/lib/riakrest/core/jiak_object.rb +233 -0
  19. data/lib/riakrest/core/jiak_schema.rb +242 -0
  20. data/lib/riakrest/core/query_link.rb +156 -0
  21. data/lib/riakrest/data/jiak_data_hash.rb +182 -0
  22. data/lib/riakrest/resource/jiak_resource.rb +628 -0
  23. data/lib/riakrest/version.rb +7 -0
  24. data/lib/riakrest.rb +164 -0
  25. data/riakrest.gemspec +38 -0
  26. data/script/console +10 -0
  27. data/script/destroy +14 -0
  28. data/script/generate +14 -0
  29. data/spec/core/exceptions_spec.rb +18 -0
  30. data/spec/core/jiak_bucket_spec.rb +103 -0
  31. data/spec/core/jiak_client_spec.rb +358 -0
  32. data/spec/core/jiak_link_spec.rb +77 -0
  33. data/spec/core/jiak_object_spec.rb +210 -0
  34. data/spec/core/jiak_schema_spec.rb +184 -0
  35. data/spec/core/query_link_spec.rb +128 -0
  36. data/spec/data/jiak_data_hash_spec.rb +14 -0
  37. data/spec/resource/jiak_resource_spec.rb +128 -0
  38. data/spec/riakrest_spec.rb +17 -0
  39. data/spec/spec.opts +5 -0
  40. data/spec/spec_helper.rb +12 -0
  41. data/tasks/rspec.rake +21 -0
  42. metadata +113 -0
@@ -0,0 +1,628 @@
1
+ module RiakRest
2
+ # JiakResource provides a resource-oriented wrapper for Jiak interaction. See
3
+ # RiakRest for a basic usage example.
4
+
5
+ module JiakResource
6
+ # ----------------------------------------------------------------------
7
+ # Class methods
8
+ # ----------------------------------------------------------------------
9
+
10
+ # Class methods for creating a user-defined JiakResource. The methods
11
+ # <code>server</code>, <code>group</code> and <code>data_class</code> are
12
+ # mandatory to create a fully usable JiakResource.
13
+ #
14
+ # ===Usage
15
+ # <code>
16
+ # class Dog
17
+ # include JiakResource
18
+ #
19
+ # server 'http://localhost:8002/jiak'
20
+ # group 'dogs'
21
+ # data_class DogData
22
+ # end
23
+ # </code>
24
+ #
25
+ module ClassMethods
26
+
27
+ # :call-seq:
28
+ # JiakServer.server(uri)
29
+ #
30
+ # Set the URI for Jiak server interaction.
31
+ def server(uri)
32
+ jiak.uri = uri
33
+ jiak.server = JiakClient.new(uri)
34
+ uri
35
+ end
36
+
37
+ # :call-seq:
38
+ # JiakResource.group(gname)
39
+ #
40
+ # Set the Jiak group name for the storage area of a resource.
41
+ def group(gname)
42
+ if(jiak.bucket.nil?)
43
+ unless(jiak.data.nil?)
44
+ create_jiak_bucket(gname,jiak.data)
45
+ else
46
+ jiak.group = gname
47
+ end
48
+ else
49
+ jiak.bucket.name = gname
50
+ end
51
+ end
52
+
53
+ # :call-seq:
54
+ # JiakResource.data_class(klass)
55
+ #
56
+ # Set the resource Jiak data class.
57
+ def data_class(klass)
58
+ if(jiak.bucket.nil?)
59
+ unless(jiak.group.nil?)
60
+ create_jiak_bucket(jiak.group,klass)
61
+ else
62
+ jiak.data = klass
63
+ end
64
+ else
65
+ old_klass = jiak.bucket.data_class
66
+ jiak.bucket.data_class = klass
67
+ create_field_accessors(klass,old_klass)
68
+ end
69
+ end
70
+
71
+ def create_jiak_bucket(gname,klass) # :nodoc:
72
+ jiak.bucket = JiakBucket.new(gname,klass)
73
+ jiak.group = jiak.bucket.name
74
+ jiak.data = klass
75
+ create_field_accessors(klass)
76
+ end
77
+ private :create_jiak_bucket
78
+
79
+ def create_field_accessors(klass,old_klass=nil)
80
+ if(old_klass)
81
+ klass.schema.allowed_fields.each do |field|
82
+ remove_method(field)
83
+ remove_method("#{field}=")
84
+ end
85
+ end
86
+
87
+ klass.schema.allowed_fields.each do |field|
88
+ define_method("#{field}=") do |val|
89
+ @jiak.obj.data.send("#{field}=",val)
90
+ if(auto_update? ||
91
+ ((auto_update? != false) && self.class.auto_update?))
92
+ self.class.put(self)
93
+ end
94
+ end
95
+ define_method("#{field}") do
96
+ @jiak.obj.data.send("#{field}")
97
+ end
98
+ end
99
+ end
100
+ private :create_jiak_bucket, :create_field_accessors
101
+
102
+ # :call-seq:
103
+ # JiakResource.params(opts={}) -> hash
104
+ #
105
+ # Default options for request parameters during Jiak interaction. Valid
106
+ # options are:
107
+ #
108
+ # <code>:reads</code> :: The number of Riak nodes that must successfully read data.
109
+ # <code>:writes</code> :: The number of Riak nodes that must successfully store data.
110
+ # <code>:durable_writes</code> :: The number of Riak nodes (<code>< writes</code>) that must successfully store data in a durable manner.
111
+ # <code>:waits</code> :: The number of Riak nodes that must reply the delete has occurred before success.
112
+ #
113
+ # Request parameters can be set at the JiakResource level using this
114
+ # method, or at the individual call level. The order of precedence for
115
+ # setting each parameter at the time of the Jiak interaction is
116
+ # individual call -> JiakResource -> Riak cluster. In general the values
117
+ # set on the Riak cluster should suffice and these parameters aren't
118
+ # necessary for Jiak interaction.
119
+ def params(opts={})
120
+ jiak.bucket.params = opts
121
+ end
122
+
123
+ # :call-seq:
124
+ # JiakResource.auto_post(state) -> true or false
125
+ #
126
+ # Set <code>true</code> to have new instances of the resource auto-posted
127
+ # to the Jiak server. Default is <code>false</code>.
128
+ def auto_post(state)
129
+ state = false if state.nil?
130
+ unless (state.is_a?(TrueClass) || state.is_a?(FalseClass))
131
+ raise JiakResource, "auto_post must be true or false"
132
+ end
133
+ jiak.auto_post = state
134
+ end
135
+
136
+ # :call-seq:
137
+ # JiakResource.auto_post? -> true or false
138
+ #
139
+ # <code>true</code> if JiakResource is set to auto-post new instances.
140
+ def auto_post?
141
+ return jiak.auto_post
142
+ end
143
+
144
+ # :call-seq:
145
+ # JiakResource.auto_update(state) -> true or false
146
+ #
147
+ # Set <code>true</code> to have changes to resource fields or links
148
+ # trigger an auto-update to the Jiak server. Default is
149
+ # <code>false</code>. Interacts with the instance-level resource
150
+ # setting. See JiakResource#auto_update.
151
+ def auto_update(state)
152
+ state = false if state.nil?
153
+ unless (state.is_a?(TrueClass) || state.is_a?(FalseClass))
154
+ raise JiakResource, "auto_update must be true or false"
155
+ end
156
+ jiak.auto_update = state
157
+ end
158
+
159
+ # :call-seq:
160
+ # JiakResource.auto_update? -> true or false
161
+ #
162
+ # <code>true</code> if JiakResource is set to auto-update.
163
+ def auto_update?
164
+ return jiak.auto_update
165
+ end
166
+
167
+ # :call-seq:
168
+ # JiakResource.schema -> JiakSchema
169
+ #
170
+ # Get the schema for a resource.
171
+ def schema
172
+ jiak.bucket.schema
173
+ end
174
+
175
+ # :call-seq:
176
+ # JiakResource.keys -> array
177
+ #
178
+ # Get an array of the current keys for this resource. Since key lists are
179
+ # updated asynchronously on a Riak cluster the returned array can be out
180
+ # of synch immediately after new puts or deletes.
181
+ def keys
182
+ jiak.server.keys(jiak.bucket)
183
+ end
184
+
185
+ # :call-seq:
186
+ # JiakResource.allowed(:f1,...,:fn) -> JiakSchema
187
+ #
188
+ # Set the allowed fields for the schema of a resource.
189
+ #
190
+ # Returns the altered JiakSchema.
191
+ def allowed(*fields)
192
+ jiak.bucket.schema.allowed_fields = *fields
193
+ jiak.bucket.schema
194
+ end
195
+
196
+ # :call-seq:
197
+ # JiakResource.required(:f1,...,:fn) -> JiakSchema
198
+ #
199
+ # Sets the required fields for the schema of a resource.
200
+ #
201
+ # Returns the altered JiakSchema.
202
+ def required(*fields)
203
+ jiak.bucket.schema.required_fields = *fields
204
+ jiak.bucket.schema
205
+ end
206
+
207
+ # :call-seq:
208
+ # JiakResource.readable(:f1,...,:fn) -> JiakSchema
209
+ #
210
+ # Sets the readable fields for the schema of a resource.
211
+ #
212
+ # Returns the altered JiakSchema.
213
+ def readable(*fields)
214
+ jiak.bucket.schema.read_mask = *fields
215
+ jiak.bucket.schema
216
+ end
217
+
218
+ # :call-seq:
219
+ # JiakResource.writable(:f1,...,:fn) -> JiakSchema
220
+ #
221
+ # Sets the writable fields for the schema of a resource.
222
+ #
223
+ # Returns the altered JiakSchema.
224
+ def writable(*fields)
225
+ jiak.bucket.schema.write_mask = *fields
226
+ jiak.bucket.schema
227
+ end
228
+
229
+ # :call-seq:
230
+ # JiakResource.readwrite(:f1,...,:fn) -> JiakSchema
231
+ #
232
+ # Set the readable and writable fields for the schema of a resource.
233
+ #
234
+ # Returns the altered JiakSchema
235
+ def readwrite(*fields)
236
+ jiak.bucket.schema.readwrite = *fields
237
+ jiak.bucket.schema
238
+ end
239
+
240
+ # :call-seq:
241
+ # JiakResource.point_of_view -> JiakSchema
242
+ #
243
+ # Ready the Jiak server point-of-view to accept structured interaction
244
+ # with a JiakResource. Returns the schema set on the Jiak server.
245
+ def point_of_view
246
+ jiak.server.set_schema(jiak.bucket)
247
+ jiak.bucket.schema
248
+ end
249
+ alias :pov :point_of_view
250
+
251
+ # :call-seq:
252
+ # JiakResource.point_of_view? -> true or false
253
+ #
254
+ # Determine if the point-of-view on the Jiak server is that of this
255
+ # JiakResource.
256
+ def point_of_view?
257
+ jiak.server.schema(jiak.bucket).eql? jiak.bucket.schema
258
+ end
259
+ alias :pov? :point_of_view?
260
+
261
+ # :call-seq:
262
+ # JiakResource.put(JiakResource,opts={}) -> JiakResource
263
+ #
264
+ # Put a JiakResource on the Jiak server. Valid options are:
265
+ #
266
+ # <code>:writes</code> :: The number of Riak nodes that must successfully store the data.
267
+ # <code>:durable_writes</code> :: The number of Riak nodes (<code>< writes</code>) that must successfully store the data in a durable manner.
268
+ # <code>:reads</code> :: The number of Riak nodes that must successfully read data being returned.
269
+ #
270
+ # If any of the request parameters <code>:writes, :durable_writes,
271
+ # :reads</code> are not set, each first defaults to the value set for the
272
+ # JiakResource class, then to the value set on the Riak cluster. In
273
+ # general the values set on the Riak cluster should suffice.
274
+ def put(resource,opts={})
275
+ opts[:object] = true
276
+ resource.jiak.obj = jiak.server.store(resource.jiak.obj,opts)
277
+ resource
278
+ end
279
+
280
+ # :call-seq:
281
+ # JiakResource.post(JiakResource,opts={}) -> JiakResource
282
+ #
283
+ # Put a JiakResource on the Jiak server with a guard to ensure the
284
+ # resource has not been previously stored. See JiakResource#put for
285
+ # options.
286
+ def post(resource,opts={})
287
+ unless(resource.jiak.obj.riak.nil?)
288
+ raise JiakResourceException, "Resource already initially stored"
289
+ end
290
+ put(resource,opts)
291
+ end
292
+
293
+ # :call-seq:
294
+ # JiakResource.update(JiakResource,opts={}) -> JiakResource
295
+ #
296
+ # Updates a JiakResource on the Jiak server with a guard to ensure the
297
+ # resource has been previously stored. See JiakResource#put for options.
298
+ def update(resource,opts={})
299
+ if(resource.jiak.obj.riak.nil?)
300
+ raise JiakResourceException, "Resource not previously stored"
301
+ end
302
+ put(resource,opts)
303
+ end
304
+
305
+ # :call-seq:
306
+ # JiakResource.get(key,opts={}) -> JiakResource
307
+ #
308
+ # Get a JiakResource on the Jiak server by the specified key. Valid
309
+ # options are:
310
+ #
311
+ # <code>:reads</code> --- The number of Riak nodes that must successfully
312
+ # reply with the data. If not set, defaults first to the value set for the
313
+ # JiakResource class, then to the value set on the Riak cluster.
314
+ def get(key,opts={})
315
+ new(jiak.server.get(jiak.bucket,key,opts))
316
+ end
317
+
318
+ # :call-seq:
319
+ # JiakResource.refresh(resource,opts={}) -> JiakResource
320
+ #
321
+ # Updates a JiakResource with the data on the Jiak server. The current
322
+ # data of the JiakResource is overwritten, so use with caution. See
323
+ # JiakResource.get for options.
324
+ def refresh(resource,opts={})
325
+ resource.jiak.obj = get(resource.jiak.obj.key,opts).jiak.obj
326
+ end
327
+
328
+ # :call-seq:
329
+ # JiakResource.delete(resource,opts={}) -> true or false
330
+ #
331
+ # Delete the JiakResource store on the Jiak server by the specified
332
+ # key. Valid options are:
333
+ #
334
+ # <code>:waits</code> --- The number of Riak nodes that must reply the
335
+ # delete has occurred before success. If not set, defaults first to the
336
+ # value set for the JiakResource, then to the value set on the Riak
337
+ # cluster. In general the values set on the Riak cluster should suffice.
338
+ def delete(resource,opts={})
339
+ jiak.server.delete(jiak.bucket,resource.jiak.obj.key,opts)
340
+ end
341
+
342
+ # :call-seq:
343
+ # JiakResource.link(from,to,tag) -> JiakResource
344
+ #
345
+ # Link from a resource to another resource by tag.
346
+ def link(from,to,tag)
347
+ link = JiakLink.new(to.jiak.obj.bucket, to.jiak.obj.key, tag)
348
+ unless from.jiak.obj.links.include?(link)
349
+ from.jiak.obj.links << link
350
+ if(from.auto_update? ||
351
+ ((from.auto_update? != false) && from.class.auto_update?))
352
+ put(from)
353
+ end
354
+ end
355
+ from
356
+ end
357
+
358
+ # :call-seq:
359
+ # JiakResource.bi_link(rscr1,rscr2,tag1_2,tag2_1=nil) -> JiakResource
360
+ #
361
+ # Link from rscr1 to rsrc2 using tag1_2 and from rscr2 to rsrc1 using
362
+ # tag2_1. tag2_1 defaults to tag1_2 if nil.
363
+ def bi_link(r1,r2,tag1_2,tag2_1=nil)
364
+ tag2_1 ||= tag1_2
365
+ link(r1,r2,tag1_2)
366
+ link(r2,r1,tag2_1)
367
+ r1
368
+ end
369
+
370
+ # :call-seq:
371
+ # JiakResource.remove_link(from,to,tag) -> true or false
372
+ def remove_link(from,to,tag)
373
+ link = JiakLink.new(to.jiak.obj.bucket, to.jiak.obj.key, tag)
374
+ has_link = from.jiak.obj.links.include?(link)
375
+ if has_link
376
+ from.jiak.obj.links.delete(link)
377
+ if(from.auto_update? ||
378
+ ((from.auto_update? != false) && from.class.auto_update?))
379
+ put(from)
380
+ end
381
+ end
382
+ has_link
383
+ end
384
+
385
+ # :call-seq:
386
+ # JiakResource.walk(from,*steps)
387
+ #
388
+ # Retrieves an array of JiakResource objects by starting with the links
389
+ # in the <code>from</code> JiakResource and doing the query steps. The
390
+ # steps are a series of query links designated by a JiakResource and a
391
+ # string tag, or a JiakResource, a string tag and a string
392
+ # accumulator. The type of JiakResource returned in the array is
393
+ # determined by the JiakResource designated in the last step.
394
+ #
395
+ # ====Usage
396
+ # <code>
397
+ # JiakResource.walk(resource,Child,'child')
398
+ # JiakResource.walk(resource,Parent,'odd',Child,'normal')
399
+ # </code>
400
+ def walk(from,*steps)
401
+ links = []
402
+ until steps.empty?
403
+ begin
404
+ klass,tag = steps.shift(2)
405
+ last_klass = klass
406
+ acc = steps[0].is_a?(String) ? steps.shift : nil
407
+ links << QueryLink.new(klass.jiak.group,tag,acc)
408
+ rescue
409
+ raise(JiakResourceException,
410
+ "each step should be Klass,tag or Klass,tag,acc")
411
+ end
412
+ end
413
+ links = links[0] if links.size == 1
414
+ jiak.server.walk(from.jiak.obj.bucket, from.jiak.obj.key, links,
415
+ last_klass.jiak.bucket.data_class).map do |jobj|
416
+ last_klass.new(jobj)
417
+ end
418
+ end
419
+
420
+ # :call-seq:
421
+ # copy(opts={}) -> JiakResource
422
+ #
423
+ # Copies a JiakResource, resetting values passed as options. Valid
424
+ # options on copy are those mandatory to create a JiakResource:
425
+ # <code>:server</code>, <code>:group</code>, and
426
+ # <code>:data_class</code>.
427
+ #
428
+ def copy(opts={})
429
+ valid = [:server,:group,:data_class]
430
+ err = opts.select {|k,v| !valid.include?(k)}
431
+ unless err.empty?
432
+ raise JiakResourceException, "unrecognized options: #{err.keys}"
433
+ end
434
+
435
+ opts[:server] ||= jiak.server.uri
436
+ opts[:group] ||= jiak.bucket.name
437
+ opts[:data_class] ||= jiak.bucket.data_class
438
+ Class.new do
439
+ include JiakResource
440
+ server opts[:server]
441
+ group opts[:group]
442
+ data_class opts[:data_class]
443
+ end
444
+ end
445
+
446
+ end
447
+
448
+ def self.included(including_class) # :nodoc:
449
+ including_class.instance_eval do
450
+ extend ClassMethods
451
+ def jiak # :nodoc:
452
+ @jiak
453
+ end
454
+ @jiak = Struct.new(:server,:uri,:group,:data,:bucket,
455
+ :auto_post,:auto_update).new
456
+ @jiak.auto_post = false
457
+ @jiak.auto_update = false
458
+ end
459
+ end
460
+
461
+ # ----------------------------------------------------------------------
462
+ # Instance methods
463
+ # ----------------------------------------------------------------------
464
+
465
+ attr_accessor :jiak # :nodoc:
466
+
467
+ # :call-seq:
468
+ # JiakResource.new(*args) -> JiakResource
469
+ #
470
+ # Create a JiakResource wrapping a JiakData instance. The argument array
471
+ # is passed to the <code>new</code> method of the JiakData associated
472
+ # with the JiakResource.
473
+ def initialize(*args)
474
+ # First form is used by JiakResource.get and JiakResource.walk
475
+ @jiak = Struct.new(:obj,:auto_update).new
476
+ if(args.size == 1 && args[0].is_a?(JiakObject))
477
+ @jiak.obj = args[0]
478
+ else
479
+ bucket = self.class.jiak.bucket
480
+ @jiak.obj = JiakObject.new(:bucket => bucket,
481
+ :data => bucket.data_class.new(*args))
482
+ if(self.class.auto_post?)
483
+ self.class.post(self)
484
+ end
485
+ end
486
+ end
487
+
488
+ # :call-seq:
489
+ # auto_update(true, false, or nil)
490
+ #
491
+ # Set to <code>true</code> to have any changes to the fields or links of
492
+ # a resource trigger an auto-update to the Jiak server. Default is
493
+ # <code>nil</code>.
494
+ #
495
+ # The setting here interacts with the class level setting
496
+ # JiakResource#ClassMethods#auto_update in the following manner:
497
+ # <code>true</code> :: Auto-update regardless of class setting.
498
+ # <code>false</code> :: No auto-update, regardless of class setting.
499
+ # <code>nil</code> :: Defer to the class setting.
500
+ def auto_update=(state)
501
+ unless (state.nil? || state.is_a?(TrueClass) || state.is_a?(FalseClass))
502
+ raise JiakResource, "auto_update must be true, false, or nil"
503
+ end
504
+ @jiak.auto_update = state
505
+ end
506
+
507
+ # :call-seq:
508
+ # auto_update? -> true, false, or nil
509
+ #
510
+ # Get current auto_update setting. See JiakResource#auto_update for settings.
511
+ def auto_update?
512
+ @jiak.auto_update
513
+ end
514
+
515
+ # :call-seq:
516
+ # put(opts={}) -> nil
517
+ #
518
+ # Put this resource on the Jiak server. See JiakResource#ClassMethods#put
519
+ # for options.
520
+ def put(opts={})
521
+ @jiak.obj = (self.class.put(self,opts)).jiak.obj
522
+ self
523
+ end
524
+
525
+ # :call-seq:
526
+ # post(opts={}) -> nil
527
+ #
528
+ # Put this resource on the Jiak server with a guard to ensure the resource
529
+ # has not been previously stored. See JiakResource#ClassMethods#put for
530
+ # options.
531
+ def post(opts={})
532
+ @jiak.obj = (self.class.post(self,opts)).jiak.obj
533
+ self
534
+ end
535
+
536
+ # :call-seq:
537
+ # update(opts={}) -> nil
538
+ #
539
+ # Put this resource on the Jiak server with a guard to ensure the resource
540
+ # has been previously stored. See JiakResource#ClassMethods#put for
541
+ # options.
542
+ def update(opts={})
543
+ @jiak.obj = (self.class.update(self,opts)).jiak.obj
544
+ self
545
+ end
546
+
547
+ # :call-seq:
548
+ # refresh(opts={}) -> nil
549
+ #
550
+ # Get this resource from the Jiak server. The current data of the resource
551
+ # is overwritten, so use with caution. See JiakResource#ClassMethods#get
552
+ # for options.
553
+ def refresh(opts={})
554
+ self.class.refresh!(self,opts)
555
+ end
556
+
557
+ # :call-seq:
558
+ # delete(opts={}) -> true or false
559
+ #
560
+ # Delete the resource on the Jiak server. The local object is
561
+ # uneffected. See JiakResource#ClassMethods#delete for options.
562
+ def delete(opts={})
563
+ self.class.delete(self,opts)
564
+ end
565
+
566
+ # :call-seq:
567
+ # link(resource,tag) -> JiakResource
568
+ #
569
+ # Link to the resource by tag.
570
+ def link(resource,tag)
571
+ self.class.link(self,resource,tag)
572
+ end
573
+
574
+ # :call-seq:
575
+ # bi_link(resource,tag,reverse_tag=nil) -> JiakResource
576
+ #
577
+ # Link to a resource by tag and back to this resource by reverse_tag. The
578
+ # value of the reverse_tag defaults to tag.
579
+ def bi_link(resource,tag,reverse_tag=nil)
580
+ self.class.bi_link(self,resource,tag,reverse_tag)
581
+ end
582
+
583
+ # :call-seq:
584
+ # remove_link(resource,tag) -> true or false
585
+ #
586
+ # Remove tagged link to resource.
587
+ def remove_link(resource,tag)
588
+ self.class.remove_link(self,resource,tag)
589
+ end
590
+
591
+ # :call-seq:
592
+ # walk(*steps) -> array
593
+ #
594
+ # Performs a Jiak walk starting at this resource. See
595
+ # JiakResource#ClassMethods#walk for description.
596
+ #
597
+ # ====Usage
598
+ # <code>
599
+ # walk(Child,'child')
600
+ # walk(Parent,'odd',Child,'normal')
601
+ # </code>
602
+ def walk(*steps)
603
+ self.class.walk(self,*steps)
604
+ end
605
+
606
+ # call-seq:
607
+ # jiak_resource == other -> true or false
608
+ #
609
+ # Equality -- Two JiakResources are equal if they wrap the same data.
610
+ def ==(other)
611
+ (@jiak.obj == other.jiak.obj) rescue false
612
+ end
613
+
614
+ # call-seq:
615
+ # eql?(other) -> true or false
616
+ #
617
+ # Returns <code>true</code> if <code>other</code> is a JiakResource
618
+ # representing the same Jiak data.
619
+ def eql?(other)
620
+ other.is_a?(JiakResource) && @jiak.obj.eql?(other.jiak.obj)
621
+ end
622
+
623
+ def hash # :nodoc:
624
+ @jiak.obj.hash
625
+ end
626
+
627
+ end
628
+ end
@@ -0,0 +1,7 @@
1
+ module RiakRest
2
+ VERSION = '0.0.1'
3
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
4
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
5
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
6
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
7
+ end