riakrest 0.1.2 → 0.1.5
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.
- data/History.txt +6 -0
- data/README.rdoc +35 -25
- data/VERSION +1 -1
- data/examples/auto_manage_data.rb +51 -0
- data/examples/auto_update_links.rb +31 -14
- data/examples/basic_client.rb +33 -10
- data/examples/basic_resource.rb +29 -12
- data/examples/basic_resource_pov.rb +65 -0
- data/examples/buoy.rb +102 -0
- data/examples/buoy_pov.rb +46 -0
- data/examples/example_helper.rb +1 -0
- data/examples/linked_resources.rb +38 -70
- data/lib/riakrest/core/jiak_client.rb +56 -31
- data/lib/riakrest/core/jiak_data.rb +24 -14
- data/lib/riakrest/core/jiak_data_fields.rb +4 -4
- data/lib/riakrest/core/query_link.rb +13 -6
- data/lib/riakrest/resource/jiak_resource.rb +85 -71
- data/lib/riakrest/resource/jiak_resource_pov.rb +279 -0
- data/lib/riakrest.rb +3 -2
- data/spec/core/jiak_client_spec.rb +20 -5
- data/spec/resource/jiak_resource_spec.rb +111 -119
- metadata +11 -4
- data/examples/auto_update_data.rb +0 -38
@@ -1,30 +1,45 @@
|
|
1
1
|
module RiakRest
|
2
|
-
# JiakResource provides
|
2
|
+
# JiakResource provides an abstraction to the Jiak interaction provided by
|
3
|
+
# the Core Client classes of RiakRest. JiakResource is built on top of Core
|
4
|
+
# Client and does not provide any functionality not possible through Core
|
5
|
+
# Client. However, JiakResource does provide a much simplier Jiak interaction
|
6
|
+
# interface.
|
3
7
|
#
|
4
8
|
# ===Example
|
5
9
|
# require 'riakrest'
|
6
10
|
# include RiakRest
|
7
11
|
#
|
8
|
-
# class
|
12
|
+
# class Person
|
9
13
|
# include JiakResource
|
10
14
|
# server 'http://localhost:8002/jiak'
|
11
|
-
#
|
15
|
+
# attr_accessor :name, :age
|
12
16
|
# auto_manage
|
13
17
|
# end
|
14
18
|
#
|
15
|
-
# remy =
|
19
|
+
# remy = Person.new(:name => 'Remy',:age => 10) # (auto-post)
|
16
20
|
# remy.age = 11 # (auto-update)
|
17
21
|
#
|
18
|
-
# callie =
|
22
|
+
# callie = Person.new(:name => 'Callie', :age => 13)
|
19
23
|
# remy.link(callie,'sister')
|
20
24
|
#
|
21
|
-
# sisters = remy.query(
|
25
|
+
# sisters = remy.query([Person,'sister'])
|
22
26
|
# sisters[0].eql?(callie) # => true
|
23
27
|
#
|
24
28
|
# remy.delete
|
25
29
|
# callie.delete
|
26
30
|
|
27
31
|
module JiakResource
|
32
|
+
|
33
|
+
# :stopdoc:
|
34
|
+
PUT_PARAMS = [:writes,:durable_writes,:reads,:copy,:read]
|
35
|
+
GET_PARAMS = [:reads,:read]
|
36
|
+
DELETE_PARAMS = [:deletes]
|
37
|
+
|
38
|
+
PUT_PARAMS.freeze
|
39
|
+
GET_PARAMS.freeze
|
40
|
+
DELETE_PARAMS.freeze
|
41
|
+
# :startdoc:
|
42
|
+
|
28
43
|
# ----------------------------------------------------------------------
|
29
44
|
# Class methods
|
30
45
|
# ----------------------------------------------------------------------
|
@@ -57,34 +72,34 @@ module RiakRest
|
|
57
72
|
end
|
58
73
|
|
59
74
|
# :call-seq:
|
60
|
-
#
|
75
|
+
# attr_reader :f1,...,:fn
|
61
76
|
#
|
62
77
|
# Add read accessible fields.
|
63
|
-
def
|
78
|
+
def attr_reader(*fields)
|
64
79
|
check_fields(fields)
|
65
80
|
added_fields = jiak.data.readable(*fields)
|
66
81
|
added_fields.each do |field|
|
67
82
|
class_eval <<-EOM
|
68
83
|
def #{field}
|
69
|
-
@jiak.data.#{field}
|
84
|
+
@jiak.object.data.#{field}
|
70
85
|
end
|
71
86
|
EOM
|
72
87
|
end
|
73
88
|
nil
|
74
89
|
end
|
75
|
-
alias :
|
90
|
+
alias :attr :attr_reader
|
76
91
|
|
77
92
|
# :call-seq:
|
78
|
-
#
|
93
|
+
# attr_writer :f1,...,:fn
|
79
94
|
#
|
80
95
|
# Add write accessible fields.
|
81
|
-
def
|
96
|
+
def attr_writer(*fields)
|
82
97
|
check_fields(fields)
|
83
98
|
added_fields = jiak.data.writable(*fields)
|
84
99
|
added_fields.each do |field|
|
85
100
|
class_eval <<-EOM
|
86
101
|
def #{field}=(val)
|
87
|
-
@jiak.data.#{field} = val
|
102
|
+
@jiak.object.data.#{field} = val
|
88
103
|
self.class.do_auto_update(self)
|
89
104
|
end
|
90
105
|
EOM
|
@@ -93,12 +108,12 @@ module RiakRest
|
|
93
108
|
end
|
94
109
|
|
95
110
|
# :call-seq:
|
96
|
-
#
|
111
|
+
# attr_accessor :f1,...,:fn
|
97
112
|
#
|
98
113
|
# Add read/write accessible fields.
|
99
|
-
def
|
100
|
-
|
101
|
-
|
114
|
+
def attr_accessor(*fields)
|
115
|
+
attr_reader *fields
|
116
|
+
attr_writer *fields
|
102
117
|
end
|
103
118
|
|
104
119
|
def check_fields(fields)
|
@@ -127,7 +142,7 @@ module RiakRest
|
|
127
142
|
# =====Valid options
|
128
143
|
# <code>:reads</code>:: Minimum number of responding nodes for successful reads.
|
129
144
|
# <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
|
145
|
+
# <code>:durable_writes</code>:: Minimum number of responding nodes that must perform a durable write to a persistence layer.
|
131
146
|
# <code>:deletes</code>:: Minimum number of responding nodes for successful delete.
|
132
147
|
#
|
133
148
|
# The configuration of a Riak cluster includes server setting for
|
@@ -258,14 +273,11 @@ module RiakRest
|
|
258
273
|
# <code>:durable_writes</code>
|
259
274
|
# <code>:reads</code>
|
260
275
|
#
|
261
|
-
#
|
262
|
-
# :reads</code> are not set, each first defaults to the value set for the
|
263
|
-
# JiakResource class, then to the value set on the Riak cluster. In
|
264
|
-
# general the values set on the Riak cluster should suffice.
|
276
|
+
# See JiakResource#params for description of options.
|
265
277
|
def put(resource,opts={})
|
278
|
+
check_opts(opts,PUT_PARAMS,JiakResourceException)
|
266
279
|
opts[:return] = :object
|
267
280
|
resource.jiak.object = jiak.client.store(resource.jiak.object,opts)
|
268
|
-
resource.jiak_convenience
|
269
281
|
resource
|
270
282
|
end
|
271
283
|
|
@@ -303,11 +315,12 @@ module RiakRest
|
|
303
315
|
# Get a JiakResource on the Jiak server by the specified key.
|
304
316
|
#
|
305
317
|
# =====Valid options:
|
306
|
-
# <code>:reads</code> --- See JiakResource#
|
318
|
+
# <code>:reads</code> --- See JiakResource#params
|
307
319
|
#
|
308
320
|
# Raise JiakResourceNotFound if no resource exists on the Jiak server for
|
309
321
|
# the key.
|
310
322
|
def get(key,opts={})
|
323
|
+
check_opts(opts,GET_PARAMS,JiakResourceException)
|
311
324
|
new(jiak.client.get(jiak.bucket,key,opts))
|
312
325
|
end
|
313
326
|
|
@@ -317,10 +330,10 @@ module RiakRest
|
|
317
330
|
# Updates a JiakResource with the data on the Jiak server. The current
|
318
331
|
# data of the JiakResource is overwritten, so use with caution.
|
319
332
|
#
|
320
|
-
# See JiakResource#
|
333
|
+
# See JiakResource#get for options.
|
321
334
|
def refresh(resource,opts={})
|
322
|
-
|
323
|
-
resource.
|
335
|
+
check_opts(opts,GET_PARAMS,JiakResourceException)
|
336
|
+
resource.jiak.object = get(resource.jiak.object.key,opts).jiak.object
|
324
337
|
end
|
325
338
|
|
326
339
|
# :call-seq:
|
@@ -330,8 +343,9 @@ module RiakRest
|
|
330
343
|
# key.
|
331
344
|
#
|
332
345
|
# =====Valid options:
|
333
|
-
# <code>:deletes</code> --- See JiakResource#
|
346
|
+
# <code>:deletes</code> --- See JiakResource#params
|
334
347
|
def delete(resource,opts={})
|
348
|
+
check_opts(opts,DELETE_PARAMS,JiakResourceException)
|
335
349
|
jiak.client.delete(jiak.bucket,resource.jiak.object.key,opts)
|
336
350
|
end
|
337
351
|
|
@@ -392,38 +406,46 @@ module RiakRest
|
|
392
406
|
end
|
393
407
|
|
394
408
|
# :call-seq:
|
395
|
-
# JiakResource.query(from
|
409
|
+
# JiakResource.query(from,steps,opts={})
|
396
410
|
#
|
397
411
|
# Retrieves an array of JiakResource objects by starting with the links
|
398
|
-
# in the <code>from</code> JiakResource and
|
399
|
-
# steps
|
400
|
-
#
|
401
|
-
#
|
402
|
-
#
|
412
|
+
# in the <code>from</code> JiakResource and performing the query
|
413
|
+
# steps. Steps is an array holding a series of query links designated by
|
414
|
+
# JiakResource,tag pairs. The type of JiakResources returned by the query
|
415
|
+
# is determined by the JiakResource class designated in the last step.
|
416
|
+
#
|
417
|
+
# Note: Although Jiak supports accumulating intermediate link step
|
418
|
+
# results, since RiakRest auto-inflates returned data intermediate
|
419
|
+
# accumulation is not supported. The most common usage, however, is to
|
420
|
+
# only accumulate the last step as supported by RiakRest.
|
403
421
|
#
|
404
422
|
# ====Usage
|
405
423
|
# <code>
|
406
|
-
# JiakResource.query(resource,Child,'child')
|
407
|
-
# JiakResource.query(resource,Parent,'odd',Child,'normal')
|
424
|
+
# JiakResource.query(resource,[Child,'child'])
|
425
|
+
# JiakResource.query(resource,[Parent,'odd',Child,'normal'])
|
408
426
|
# </code>
|
409
|
-
def query(from
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
links << QueryLink.new(klass.jiak.
|
417
|
-
rescue
|
418
|
-
raise(JiakResourceException,
|
419
|
-
"each step should be Klass,tag or Klass,tag,acc")
|
427
|
+
def query(from,steps,opts={})
|
428
|
+
check_opts(opts,GET_PARAMS,JiakResourceException)
|
429
|
+
begin
|
430
|
+
links = []
|
431
|
+
klass = nil
|
432
|
+
steps.each_slice(2) do |pair|
|
433
|
+
klass = pair[0]
|
434
|
+
links << QueryLink.new(klass.jiak.bucket.name,pair[1],nil)
|
420
435
|
end
|
436
|
+
data_class = klass.jiak.bucket.data_class
|
437
|
+
if(klass.include?(JiakResourcePOV))
|
438
|
+
opts[:read] = klass.jiak.read_mask
|
439
|
+
end
|
440
|
+
jiak.client.walk(from.jiak.object.bucket,
|
441
|
+
from.jiak.object.key,
|
442
|
+
links,
|
443
|
+
data_class,
|
444
|
+
opts).map {|jobj| klass.new(jobj)}
|
445
|
+
# rescue
|
446
|
+
# raise(JiakResourceException,
|
447
|
+
# "each step should be JiakResource,tag pair")
|
421
448
|
end
|
422
|
-
links = links[0] if links.size == 1
|
423
|
-
jiak.client.walk(from.jiak.object.bucket, from.jiak.object.key, links,
|
424
|
-
last_klass.jiak.bucket.data_class).map do |jobj|
|
425
|
-
last_klass.new(jobj)
|
426
|
-
end
|
427
449
|
end
|
428
450
|
alias :walk :query
|
429
451
|
|
@@ -483,7 +505,7 @@ module RiakRest
|
|
483
505
|
# with the JiakResource.
|
484
506
|
def initialize(*args)
|
485
507
|
# First form is used by JiakResource.get and JiakResource.query
|
486
|
-
@jiak = Struct.new(:object,:
|
508
|
+
@jiak = Struct.new(:object,:auto_update).new
|
487
509
|
if(args.size == 1 && args[0].is_a?(JiakObject))
|
488
510
|
@jiak.object = args[0]
|
489
511
|
else
|
@@ -498,16 +520,6 @@ module RiakRest
|
|
498
520
|
self.class.post(self)
|
499
521
|
end
|
500
522
|
end
|
501
|
-
jiak_convenience
|
502
|
-
end
|
503
|
-
|
504
|
-
# Public method as a by-product of implementation. No harm done in calling
|
505
|
-
# this method, as it will just repeat assignments already done.
|
506
|
-
def jiak_convenience # :nodoc:
|
507
|
-
@jiak.bucket = @jiak.object.bucket
|
508
|
-
@jiak.key = @jiak.object.key
|
509
|
-
@jiak.data = @jiak.object.data
|
510
|
-
@jiak.links = @jiak.object.links
|
511
523
|
end
|
512
524
|
|
513
525
|
# :call-seq:
|
@@ -545,7 +557,6 @@ module RiakRest
|
|
545
557
|
# for options.
|
546
558
|
def put(opts={})
|
547
559
|
@jiak.object = (self.class.put(self,opts)).jiak.object
|
548
|
-
jiak_convenience
|
549
560
|
self
|
550
561
|
end
|
551
562
|
|
@@ -557,7 +568,6 @@ module RiakRest
|
|
557
568
|
# options.
|
558
569
|
def post(opts={})
|
559
570
|
@jiak.object = (self.class.post(self,opts)).jiak.object
|
560
|
-
jiak_convenience
|
561
571
|
self
|
562
572
|
end
|
563
573
|
|
@@ -569,7 +579,6 @@ module RiakRest
|
|
569
579
|
# options.
|
570
580
|
def update(opts={})
|
571
581
|
@jiak.object = (self.class.update(self,opts)).jiak.object
|
572
|
-
jiak_convenience
|
573
582
|
self
|
574
583
|
end
|
575
584
|
alias :push :update
|
@@ -632,21 +641,26 @@ module RiakRest
|
|
632
641
|
end
|
633
642
|
|
634
643
|
# :call-seq:
|
635
|
-
# query(
|
644
|
+
# query(steps) -> array
|
636
645
|
#
|
637
646
|
# Performs a Jiak query starting at this resource. See
|
638
647
|
# JiakResource#ClassMethods#query for description.
|
639
648
|
#
|
640
649
|
# ====Usage
|
641
650
|
# <code>
|
642
|
-
# query(Child,'child')
|
643
|
-
# query(Parent,'odd',Child,'normal')
|
651
|
+
# query([Child,'child'])
|
652
|
+
# query([Parent,'odd',Child,'normal'])
|
644
653
|
# </code>
|
645
|
-
def query(
|
646
|
-
self.class.query(self
|
654
|
+
def query(steps,opts={})
|
655
|
+
self.class.query(self,steps)
|
647
656
|
end
|
648
657
|
alias :walk :query
|
649
658
|
|
659
|
+
# CxINC
|
660
|
+
def pov(pov)
|
661
|
+
pov.get(@jiak.object.key)
|
662
|
+
end
|
663
|
+
|
650
664
|
# :call-seq:
|
651
665
|
# jiak_resource == other -> true or false
|
652
666
|
#
|
@@ -0,0 +1,279 @@
|
|
1
|
+
module RiakRest
|
2
|
+
|
3
|
+
# JiakResourcePOV provides a restricted interface to existing JiakResource
|
4
|
+
# data. This restriction offers two primary benefits: Only explicitly
|
5
|
+
# declared fields can be read or written via the POV, thereby protecting
|
6
|
+
# other JiakResource fields, and only the POV fields are transported to and
|
7
|
+
# from the Jiak server, thereby reducing the HTTP message sizes.
|
8
|
+
#
|
9
|
+
# ===Example
|
10
|
+
# require 'riakrest'
|
11
|
+
# include RiakRest
|
12
|
+
#
|
13
|
+
# class AB
|
14
|
+
# include JiakResource
|
15
|
+
# server SERVER_URI
|
16
|
+
# group "test"
|
17
|
+
# attr_accessor :a, :b
|
18
|
+
# keygen { "k#{a}" }
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# class A
|
22
|
+
# include JiakResourcePOV
|
23
|
+
# resource AB
|
24
|
+
# attr_accessor :a
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# ab = AB.new(:a => 1, :b => 2)
|
28
|
+
# ab.post
|
29
|
+
#
|
30
|
+
# a = ab.pov(A)
|
31
|
+
# a.a = 11
|
32
|
+
# a.update
|
33
|
+
#
|
34
|
+
# ab.refresh
|
35
|
+
# ab.a # => 11
|
36
|
+
|
37
|
+
module JiakResourcePOV
|
38
|
+
|
39
|
+
# ----------------------------------------------------------------------
|
40
|
+
# Class methods
|
41
|
+
# ----------------------------------------------------------------------
|
42
|
+
|
43
|
+
# Class methods for creating a user-defined JiakResourcePOV.
|
44
|
+
#
|
45
|
+
# See JiakResourcePOV for example usage.
|
46
|
+
module ClassMethods
|
47
|
+
|
48
|
+
# :call-seq:
|
49
|
+
# JiakResourcePOV.resource(resource)
|
50
|
+
#
|
51
|
+
# Set the JiakResource to which this JiakResourcePOV is a point-of-view.
|
52
|
+
def resource(resource)
|
53
|
+
@resource = resource
|
54
|
+
@jiak.bucket = JiakBucket.new(@resource.jiak.group,
|
55
|
+
JiakDataFields.create)
|
56
|
+
end
|
57
|
+
|
58
|
+
# :call-seq:
|
59
|
+
# attr_reader :f1,...,:fn
|
60
|
+
#
|
61
|
+
# Add read accessible fields.
|
62
|
+
def attr_reader(*fields)
|
63
|
+
check_fields(fields,@resource.schema.read_mask)
|
64
|
+
added_fields = @jiak.bucket.data_class.readable(*fields)
|
65
|
+
added_fields.each do |field|
|
66
|
+
class_eval <<-EOM
|
67
|
+
def #{field}
|
68
|
+
@jiak.object.data.#{field}
|
69
|
+
end
|
70
|
+
EOM
|
71
|
+
end
|
72
|
+
@jiak.read_mask = @jiak.bucket.data_class.schema.read_mask.join(',')
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
# :call-seq:
|
77
|
+
# attr_writer :f1,...,:fn
|
78
|
+
#
|
79
|
+
# Add write accessible fields.
|
80
|
+
def attr_writer(*fields)
|
81
|
+
check_fields(fields,@resource.schema.write_mask)
|
82
|
+
added_fields = @jiak.bucket.data_class.writable(*fields)
|
83
|
+
added_fields.each do |field|
|
84
|
+
class_eval <<-EOM
|
85
|
+
def #{field}=(val)
|
86
|
+
@jiak.object.data.#{field} = val
|
87
|
+
self.class.do_auto_update(self)
|
88
|
+
end
|
89
|
+
EOM
|
90
|
+
end
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# :call-seq:
|
95
|
+
# attr_accessor :f1,...,:fn
|
96
|
+
#
|
97
|
+
# Add read/write accessible fields.
|
98
|
+
def attr_accessor(*fields)
|
99
|
+
attr_reader(*fields)
|
100
|
+
attr_writer(*fields)
|
101
|
+
end
|
102
|
+
|
103
|
+
def check_fields(fields,valid)
|
104
|
+
invalid = fields.select {|f| !valid.include?(f)}
|
105
|
+
unless(invalid.empty?)
|
106
|
+
raise(JiakResourcePOVException,"invalid fields: #{invalid.inspect}")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
private :check_fields
|
110
|
+
|
111
|
+
# :call-seq:
|
112
|
+
# JiakResourcePOV.keys -> array
|
113
|
+
#
|
114
|
+
# Get an array of the current keys for this resource. Since key lists are
|
115
|
+
# updated asynchronously on a Riak cluster the returned array can be out
|
116
|
+
# of synch immediately after new puts or deletes.
|
117
|
+
def keys
|
118
|
+
@resource.jiak.client.keys(jiak.bucket)
|
119
|
+
end
|
120
|
+
|
121
|
+
# :call-seq:
|
122
|
+
# JiakResourcePOV.get(key,opts={}) -> JiakResourcePOV
|
123
|
+
#
|
124
|
+
# Get a JiakResourcePOV on the Jiak server by the specified key.
|
125
|
+
#
|
126
|
+
# =====Valid options:
|
127
|
+
# <code>:reads</code> --- See JiakResource#get
|
128
|
+
#
|
129
|
+
# Raise JiakResourceNotFound if no resource exists on the Jiak server for
|
130
|
+
# the key.
|
131
|
+
def get(key,opts={})
|
132
|
+
opts[:read] = @jiak.read_mask
|
133
|
+
new(@resource.jiak.client.get(@jiak.bucket,key,opts))
|
134
|
+
end
|
135
|
+
|
136
|
+
# :call-seq:
|
137
|
+
# JiakResourcePOV.update(JiakResourcePOV,opts={}) -> JiakResourcePOV
|
138
|
+
#
|
139
|
+
# Updates a JiakResourcePOV on the Jiak server.
|
140
|
+
#
|
141
|
+
# See JiakResource#put for options.
|
142
|
+
def update(resource,opts={})
|
143
|
+
opts[:copy] = true
|
144
|
+
opts[:read] = @jiak.read_mask
|
145
|
+
@resource.put(resource,opts)
|
146
|
+
end
|
147
|
+
|
148
|
+
# :call-seq:
|
149
|
+
# JiakResourcePOV.refresh(resource,opts={}) -> JiakResourcePOV
|
150
|
+
#
|
151
|
+
# Updates a JiakResource with the data on the Jiak server. The current
|
152
|
+
# data of the JiakResource is overwritten, so use with caution.
|
153
|
+
#
|
154
|
+
# See JiakResource#refresh for options.
|
155
|
+
def refresh(resource,opts={})
|
156
|
+
resource.jiak.object = get(resource.jiak.object.key,opts).jiak.object
|
157
|
+
end
|
158
|
+
|
159
|
+
# :call-seq:
|
160
|
+
# JiakResourcePOV.exist?(key) -> true or false
|
161
|
+
#
|
162
|
+
# Determine if a resource exists on the Jiak server for a key.
|
163
|
+
def exist?(key)
|
164
|
+
@resource.jiak.client.exist?(@jiak.bucket,key)
|
165
|
+
end
|
166
|
+
|
167
|
+
# :call-seq:
|
168
|
+
# JiakResourcePOV.do_auto_update(resource) -> JiakResourcePOV or nil
|
169
|
+
#
|
170
|
+
# Determine if an auto update should be done on the resource and perform
|
171
|
+
# an update if so.
|
172
|
+
#
|
173
|
+
# Public method as a by-product of implementation.
|
174
|
+
def do_auto_update(rsrc) # :no-doc:
|
175
|
+
if(rsrc.auto_update? ||
|
176
|
+
((rsrc.auto_update? != false) && rsrc.class.auto_update?))
|
177
|
+
update(rsrc)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.included(including_class) # :nodoc:
|
184
|
+
including_class.instance_eval do
|
185
|
+
extend ClassMethods
|
186
|
+
|
187
|
+
def jiak # :nodoc:
|
188
|
+
@jiak
|
189
|
+
end
|
190
|
+
|
191
|
+
@jiak = Struct.new(:bucket,:auto_update,:read_mask).new
|
192
|
+
@jiak.auto_update = false
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# ----------------------------------------------------------------------
|
197
|
+
# Instance methods
|
198
|
+
# ----------------------------------------------------------------------
|
199
|
+
|
200
|
+
attr_reader :jiak # :nodoc:
|
201
|
+
|
202
|
+
def initialize(jobj) # :nodoc:
|
203
|
+
unless(jobj.is_a?(JiakObject))
|
204
|
+
# CxINC
|
205
|
+
raise JiakException
|
206
|
+
end
|
207
|
+
@jiak = Struct.new(:object,:auto_update).new
|
208
|
+
@jiak.object = jobj
|
209
|
+
@jiak.auto_update = false
|
210
|
+
end
|
211
|
+
# CxINC
|
212
|
+
# private_class_method :new
|
213
|
+
|
214
|
+
# :call-seq:
|
215
|
+
# auto_update(true, false, or nil)
|
216
|
+
#
|
217
|
+
# See JiakResource#auto_update
|
218
|
+
def auto_update=(state)
|
219
|
+
unless (state.nil? || state.is_a?(TrueClass) || state.is_a?(FalseClass))
|
220
|
+
raise JiakResource, "auto_update must be true, false, or nil"
|
221
|
+
end
|
222
|
+
@jiak.auto_update = state
|
223
|
+
end
|
224
|
+
|
225
|
+
# :call-seq:
|
226
|
+
# auto_update? -> true, false, or nil
|
227
|
+
#
|
228
|
+
# See JiakResource#auto_update?
|
229
|
+
def auto_update?
|
230
|
+
@jiak.auto_update
|
231
|
+
end
|
232
|
+
|
233
|
+
# :call-seq:
|
234
|
+
# update(opts={}) -> nil
|
235
|
+
#
|
236
|
+
# Put this resource on the Jiak server. See JiakResource#ClassMethods#put
|
237
|
+
# for options.
|
238
|
+
def update(opts={})
|
239
|
+
@jiak.object = (self.class.update(self,opts)).jiak.object
|
240
|
+
self
|
241
|
+
end
|
242
|
+
alias :push :update
|
243
|
+
|
244
|
+
# :call-seq:
|
245
|
+
# refresh(opts={}) -> nil
|
246
|
+
#
|
247
|
+
# Get this resource from the Jiak server. The current data of the resource
|
248
|
+
# is overwritten, so use with caution. See JiakResource#ClassMethods#get
|
249
|
+
# for options.
|
250
|
+
def refresh(opts={})
|
251
|
+
self.class.refresh(self,opts)
|
252
|
+
end
|
253
|
+
alias :pull :refresh
|
254
|
+
|
255
|
+
# :call-seq:
|
256
|
+
# jiak_resource == other -> true or false
|
257
|
+
#
|
258
|
+
# Equality -- Two JiakResourcePOVs are equal if they wrap the same Jiak
|
259
|
+
# data.
|
260
|
+
def ==(other)
|
261
|
+
(@jiak.object == other.jiak.object) rescue false
|
262
|
+
end
|
263
|
+
|
264
|
+
# :call-seq:
|
265
|
+
# eql?(other) -> true or false
|
266
|
+
#
|
267
|
+
# Returns <code>true</code> if <code>other</code> is a JiakResourcePOV
|
268
|
+
# representing the same Jiak data.
|
269
|
+
def eql?(other)
|
270
|
+
other.is_a?(JiakResourcePOV) && @jiak.object.eql?(other.jiak.object)
|
271
|
+
end
|
272
|
+
|
273
|
+
def hash # :nodoc:
|
274
|
+
@jiak.object.hash
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
end
|
279
|
+
end
|
data/lib/riakrest.rb
CHANGED
@@ -36,7 +36,7 @@ $:.unshift(dirname) unless
|
|
36
36
|
# class People
|
37
37
|
# include JiakResource
|
38
38
|
# server 'http://localhost:8002/jiak'
|
39
|
-
#
|
39
|
+
# attr_accessor :name, :age
|
40
40
|
# auto_manage
|
41
41
|
# end
|
42
42
|
#
|
@@ -46,7 +46,7 @@ $:.unshift(dirname) unless
|
|
46
46
|
# callie = People.new(:name => 'Callie', :age => 13)
|
47
47
|
# remy.link(callie,'sister')
|
48
48
|
#
|
49
|
-
# sisters = remy.query(People,'sister')
|
49
|
+
# sisters = remy.query([People,'sister'])
|
50
50
|
# sisters[0].eql?(callie) # => true
|
51
51
|
#
|
52
52
|
# remy.delete
|
@@ -88,6 +88,7 @@ require 'riakrest/core/jiak_schema'
|
|
88
88
|
require 'riakrest/core/query_link'
|
89
89
|
|
90
90
|
require 'riakrest/resource/jiak_resource'
|
91
|
+
require 'riakrest/resource/jiak_resource_pov'
|
91
92
|
|
92
93
|
# Extend Array with convenience methods for comparing array contents.
|
93
94
|
class Array # :nodoc:
|
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
3
3
|
class FooBarBaz # :nodoc:
|
4
4
|
include JiakData
|
5
5
|
|
6
|
-
|
6
|
+
attr_accessor :foo, :bar
|
7
7
|
require :foo
|
8
8
|
allow :baz
|
9
9
|
end
|
@@ -44,12 +44,27 @@ describe "JiakClient" do
|
|
44
44
|
no_no = lambda {JiakClient::DELETES << 'a'}
|
45
45
|
no_no.should raise_error(StandardError,/frozen/)
|
46
46
|
|
47
|
-
no_no = lambda {JiakClient::
|
47
|
+
no_no = lambda {JiakClient::COPY << 'a'}
|
48
48
|
no_no.should raise_error(StandardError,/frozen/)
|
49
49
|
|
50
|
-
no_no = lambda {JiakClient::
|
50
|
+
no_no = lambda {JiakClient::READ << 'a'}
|
51
51
|
no_no.should raise_error(StandardError,/frozen/)
|
52
|
-
|
52
|
+
|
53
|
+
no_no = lambda {JiakClient::CLIENT_PARAMS << 'a'}
|
54
|
+
no_no.should raise_error(StandardError,/frozen/)
|
55
|
+
|
56
|
+
no_no = lambda {JiakClient::STORE_PARAMS << 'a'}
|
57
|
+
no_no.should raise_error(StandardError,/frozen/)
|
58
|
+
|
59
|
+
no_no = lambda {JiakClient::GET_PARAMS << 'a'}
|
60
|
+
no_no.should raise_error(StandardError,/frozen/)
|
61
|
+
|
62
|
+
no_no = lambda {JiakClient::DELETE_PARAMS << 'a'}
|
63
|
+
no_no.should raise_error(StandardError,/frozen/)
|
64
|
+
|
65
|
+
no_no = lambda {JiakClient::WALK_PARAMS << 'a'}
|
66
|
+
no_no.should raise_error(StandardError,/frozen/)
|
67
|
+
|
53
68
|
no_no = lambda {JiakClient::KEYS << 'a'}
|
54
69
|
no_no.should raise_error(StandardError,/frozen/)
|
55
70
|
|
@@ -340,7 +355,7 @@ end
|
|
340
355
|
|
341
356
|
class PersonData
|
342
357
|
include JiakData
|
343
|
-
|
358
|
+
attr_accessor :name
|
344
359
|
end
|
345
360
|
|
346
361
|
describe "JiakClient links" do
|