riakrest 0.0.4 → 0.1.0
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 +25 -26
- data/README.rdoc +16 -26
- data/VERSION +1 -1
- data/examples/auto_update_data.rb +16 -21
- data/examples/auto_update_links.rb +17 -21
- data/examples/basic_client.rb +15 -11
- data/examples/basic_resource.rb +14 -18
- data/examples/bucket_schemas.rb +12 -10
- data/examples/linked_resources.rb +23 -26
- data/examples/links_only_pov.rb +25 -25
- data/examples/multiple_pov.rb +16 -14
- data/examples/rest_interaction.rb +5 -5
- data/examples/ruby_json_data.rb +1 -19
- data/lib/riakrest/core/jiak_bucket.rb +18 -50
- data/lib/riakrest/core/jiak_client.rb +147 -79
- data/lib/riakrest/core/jiak_data.rb +179 -164
- data/lib/riakrest/core/jiak_data_fields.rb +69 -0
- data/lib/riakrest/core/jiak_link.rb +6 -8
- data/lib/riakrest/core/jiak_object.rb +15 -13
- data/lib/riakrest/core/jiak_schema.rb +192 -57
- data/lib/riakrest/resource/jiak_resource.rb +118 -170
- data/lib/riakrest.rb +24 -103
- data/spec/core/jiak_bucket_spec.rb +15 -45
- data/spec/core/jiak_client_spec.rb +70 -41
- data/spec/core/jiak_link_spec.rb +2 -2
- data/spec/core/jiak_object_spec.rb +12 -12
- data/spec/core/jiak_schema_spec.rb +122 -18
- data/spec/resource/jiak_resource_spec.rb +115 -148
- metadata +3 -5
- data/lib/riakrest/data/jiak_data_hash.rb +0 -182
- data/spec/data/jiak_data_hash_spec.rb +0 -14
@@ -1,27 +1,37 @@
|
|
1
1
|
module RiakRest
|
2
|
-
# JiakResource provides a resource-oriented wrapper for Jiak interaction.
|
3
|
-
#
|
2
|
+
# JiakResource provides a resource-oriented wrapper for Jiak interaction.
|
3
|
+
#
|
4
|
+
# ===Example
|
5
|
+
# require 'riakrest'
|
6
|
+
# include RiakRest
|
7
|
+
#
|
8
|
+
# class People
|
9
|
+
# include JiakResource
|
10
|
+
# server 'http://localhost:8002/jiak'
|
11
|
+
# jattr_accessor :name, :age
|
12
|
+
# auto_manage
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# remy = People.new(:name => 'Remy',:age => 10) # (auto-post)
|
16
|
+
# remy.age = 11 # (auto-update)
|
17
|
+
#
|
18
|
+
# callie = People.new(:name => 'Callie', :age => 13)
|
19
|
+
# remy.link(callie,'sister')
|
20
|
+
#
|
21
|
+
# sisters = remy.query(People,'sister')
|
22
|
+
# sisters[0].eql?(callie) # => true
|
23
|
+
#
|
24
|
+
# remy.delete
|
25
|
+
# callie.delete
|
4
26
|
|
5
27
|
module JiakResource
|
6
28
|
# ----------------------------------------------------------------------
|
7
29
|
# Class methods
|
8
30
|
# ----------------------------------------------------------------------
|
9
31
|
|
10
|
-
# Class methods for creating a user-defined JiakResource.
|
11
|
-
# <code>server</code>, <code>group</code> and <code>data_class</code> are
|
12
|
-
# mandatory to create a fully usable JiakResource.
|
32
|
+
# Class methods for creating a user-defined JiakResource.
|
13
33
|
#
|
14
|
-
#
|
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
|
-
#
|
34
|
+
# See JiakResource for example usage.
|
25
35
|
module ClassMethods
|
26
36
|
|
27
37
|
# :call-seq:
|
@@ -33,9 +43,8 @@ module RiakRest
|
|
33
43
|
# Valid options:
|
34
44
|
# <code>:proxy</code> Proxy server URI.
|
35
45
|
def server(uri,opts={})
|
36
|
-
jiak.uri = uri
|
37
46
|
jiak.server = JiakClient.new(uri,opts)
|
38
|
-
uri
|
47
|
+
jiak.uri = uri
|
39
48
|
end
|
40
49
|
|
41
50
|
# :call-seq:
|
@@ -43,63 +52,64 @@ module RiakRest
|
|
43
52
|
#
|
44
53
|
# Set the Jiak group name for the storage area of a resource.
|
45
54
|
def group(gname)
|
46
|
-
|
47
|
-
|
48
|
-
create_jiak_bucket(gname,jiak.data)
|
49
|
-
else
|
50
|
-
jiak.group = gname
|
51
|
-
end
|
52
|
-
else
|
53
|
-
jiak.bucket.name = gname
|
54
|
-
end
|
55
|
+
jiak.group = gname
|
56
|
+
jiak.bucket.name = gname
|
55
57
|
end
|
56
58
|
|
57
59
|
# :call-seq:
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
jiak.data
|
60
|
+
# jattr_reader :f1,...,:fn
|
61
|
+
#
|
62
|
+
# Add read accessible fields.
|
63
|
+
def jattr_reader(*fields)
|
64
|
+
check_fields(fields)
|
65
|
+
added_fields = jiak.data.readable(*fields)
|
66
|
+
added_fields.each do |field|
|
67
|
+
define_method("#{field}") do
|
68
|
+
@jiak.data.send("#{field}")
|
67
69
|
end
|
68
|
-
else
|
69
|
-
old_klass = jiak.bucket.data_class
|
70
|
-
jiak.bucket.data_class = klass
|
71
|
-
create_field_accessors(klass,old_klass)
|
72
70
|
end
|
71
|
+
nil
|
73
72
|
end
|
74
|
-
|
75
|
-
def create_jiak_bucket(gname,klass) # :nodoc:
|
76
|
-
jiak.bucket = JiakBucket.new(gname,klass)
|
77
|
-
jiak.group = jiak.bucket.name
|
78
|
-
jiak.data = klass
|
79
|
-
create_field_accessors(klass)
|
80
|
-
end
|
81
|
-
private :create_jiak_bucket
|
82
|
-
|
83
|
-
def create_field_accessors(klass,old_klass=nil)
|
84
|
-
if(old_klass)
|
85
|
-
klass.schema.allowed_fields.each do |field|
|
86
|
-
remove_method(field)
|
87
|
-
remove_method("#{field}=")
|
88
|
-
end
|
89
|
-
end
|
73
|
+
alias :jattr :jattr_reader
|
90
74
|
|
91
|
-
|
75
|
+
# :call-seq:
|
76
|
+
# jattr_writer :f1,...,:fn
|
77
|
+
#
|
78
|
+
# Add write accessible fields.
|
79
|
+
def jattr_writer(*fields)
|
80
|
+
check_fields(fields)
|
81
|
+
added_fields = jiak.data.writable(*fields)
|
82
|
+
added_fields.each do |field|
|
92
83
|
define_method("#{field}=") do |val|
|
93
|
-
@jiak.
|
84
|
+
@jiak.data.send("#{field}=",val)
|
94
85
|
self.class.do_auto_update(self)
|
95
|
-
val
|
96
|
-
end
|
97
|
-
define_method("#{field}") do
|
98
|
-
@jiak.object.data.send("#{field}")
|
99
86
|
end
|
100
87
|
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
# :call-seq:
|
92
|
+
# jattr_accessor :f1,...,:fn
|
93
|
+
#
|
94
|
+
# Add read/write accessible fields.
|
95
|
+
def jattr_accessor(*fields)
|
96
|
+
jattr_reader *fields
|
97
|
+
jattr_writer *fields
|
98
|
+
end
|
99
|
+
|
100
|
+
def check_fields(fields)
|
101
|
+
if(fields.include?(:jiak) || fields.include?('jiak'))
|
102
|
+
raise(JiakResourceException,
|
103
|
+
"'jiak' reserved for RiakRest Resource usage")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
private :check_fields
|
107
|
+
|
108
|
+
def keygen(&block)
|
109
|
+
jiak.data.class_eval <<-EOS
|
110
|
+
define_method(:keygen,&block)
|
111
|
+
EOS
|
101
112
|
end
|
102
|
-
private :create_jiak_bucket, :create_field_accessors
|
103
113
|
|
104
114
|
# :call-seq:
|
105
115
|
# JiakResource.params(opts={}) -> hash
|
@@ -119,16 +129,18 @@ module RiakRest
|
|
119
129
|
# set on the Riak cluster should suffice and these parameters aren't
|
120
130
|
# necessary for Jiak interaction.
|
121
131
|
def params(opts={})
|
122
|
-
jiak.
|
132
|
+
jiak.server.params = opts
|
123
133
|
end
|
124
134
|
|
125
135
|
# :call-seq:
|
126
136
|
# JiakResource.auto_post(state) -> true or false
|
127
137
|
#
|
128
138
|
# Set <code>true</code> to have new instances of the resource auto-posted
|
129
|
-
# to the Jiak server.
|
130
|
-
|
131
|
-
|
139
|
+
# to the Jiak server.
|
140
|
+
#
|
141
|
+
# Default value for state is <code>true</code>. Note the default behavior
|
142
|
+
# for JiakResource is auto-post false.
|
143
|
+
def auto_post(state=true)
|
132
144
|
unless (state.is_a?(TrueClass) || state.is_a?(FalseClass))
|
133
145
|
raise JiakResource, "auto_post must be true or false"
|
134
146
|
end
|
@@ -147,10 +159,12 @@ module RiakRest
|
|
147
159
|
# JiakResource.auto_update(state) -> true or false
|
148
160
|
#
|
149
161
|
# Set <code>true</code> to have changes to resource fields or links
|
150
|
-
# trigger an auto-update to the Jiak server.
|
151
|
-
#
|
152
|
-
#
|
153
|
-
|
162
|
+
# trigger an auto-update to the Jiak server. Interacts with the
|
163
|
+
# instance-level resource setting. See JiakResource#auto_update.
|
164
|
+
#
|
165
|
+
# Default value for state is <code>true</code>. Note the default behavior
|
166
|
+
# for JiakResource is auto-update false.
|
167
|
+
def auto_update(state=true)
|
154
168
|
state = false if state.nil?
|
155
169
|
unless (state.is_a?(TrueClass) || state.is_a?(FalseClass))
|
156
170
|
raise JiakResource, "auto_update must be true or false"
|
@@ -167,79 +181,30 @@ module RiakRest
|
|
167
181
|
end
|
168
182
|
|
169
183
|
# :call-seq:
|
170
|
-
# JiakResource.
|
171
|
-
#
|
172
|
-
# Get the schema for a resource.
|
173
|
-
def schema
|
174
|
-
jiak.bucket.schema
|
175
|
-
end
|
176
|
-
|
177
|
-
# :call-seq:
|
178
|
-
# JiakResource.keys -> array
|
184
|
+
# JiakResource.auto_manage(state) -> true or false
|
179
185
|
#
|
180
|
-
#
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
jiak.server.keys(jiak.bucket)
|
186
|
+
# Set auto-post and auto-manage simultaneously.
|
187
|
+
def auto_manage(state=true)
|
188
|
+
auto_post state
|
189
|
+
auto_update state
|
185
190
|
end
|
186
191
|
|
187
192
|
# :call-seq:
|
188
|
-
# JiakResource.
|
189
|
-
#
|
190
|
-
# Set the allowed fields for the schema of a resource.
|
191
|
-
#
|
192
|
-
# Returns the altered JiakSchema.
|
193
|
-
def allowed(*fields)
|
194
|
-
jiak.bucket.schema.allowed_fields = *fields
|
195
|
-
jiak.bucket.schema
|
196
|
-
end
|
197
|
-
|
198
|
-
# :call-seq:
|
199
|
-
# JiakResource.required(:f1,...,:fn) -> JiakSchema
|
200
|
-
#
|
201
|
-
# Sets the required fields for the schema of a resource.
|
202
|
-
#
|
203
|
-
# Returns the altered JiakSchema.
|
204
|
-
def required(*fields)
|
205
|
-
jiak.bucket.schema.required_fields = *fields
|
206
|
-
jiak.bucket.schema
|
207
|
-
end
|
208
|
-
|
209
|
-
# :call-seq:
|
210
|
-
# JiakResource.readable(:f1,...,:fn) -> JiakSchema
|
211
|
-
#
|
212
|
-
# Sets the readable fields for the schema of a resource.
|
193
|
+
# JiakResource.auto_update? -> true or false
|
213
194
|
#
|
214
|
-
#
|
215
|
-
def
|
216
|
-
|
217
|
-
jiak.bucket.schema
|
195
|
+
# <code>true</code> if JiakResource is set to auto-update.
|
196
|
+
def auto_manage?
|
197
|
+
return auto_post? && auto_update?
|
218
198
|
end
|
219
199
|
|
220
200
|
# :call-seq:
|
221
|
-
# JiakResource.
|
222
|
-
#
|
223
|
-
# Sets the writable fields for the schema of a resource.
|
201
|
+
# JiakResource.schema -> JiakSchema
|
224
202
|
#
|
225
|
-
#
|
226
|
-
def
|
227
|
-
jiak.
|
228
|
-
jiak.bucket.schema
|
203
|
+
# Get the schema for a resource.
|
204
|
+
def schema
|
205
|
+
jiak.data.schema
|
229
206
|
end
|
230
207
|
|
231
|
-
# :call-seq:
|
232
|
-
# JiakResource.readwrite(:f1,...,:fn) -> JiakSchema
|
233
|
-
#
|
234
|
-
# Set the readable and writable fields for the schema of a resource.
|
235
|
-
#
|
236
|
-
# Returns the altered JiakSchema
|
237
|
-
def readwrite(*fields)
|
238
|
-
jiak.bucket.schema.readwrite = *fields
|
239
|
-
jiak.bucket.schema
|
240
|
-
end
|
241
|
-
|
242
|
-
# :call-seq:
|
243
208
|
# JiakResource.point_of_view -> JiakSchema
|
244
209
|
#
|
245
210
|
# Ready the Jiak server point-of-view to accept structured interaction
|
@@ -260,6 +225,16 @@ module RiakRest
|
|
260
225
|
end
|
261
226
|
alias :pov? :point_of_view?
|
262
227
|
|
228
|
+
# :call-seq:
|
229
|
+
# JiakResource.keys -> array
|
230
|
+
#
|
231
|
+
# Get an array of the current keys for this resource. Since key lists are
|
232
|
+
# updated asynchronously on a Riak cluster the returned array can be out
|
233
|
+
# of synch immediately after new puts or deletes.
|
234
|
+
def keys
|
235
|
+
jiak.server.keys(jiak.bucket)
|
236
|
+
end
|
237
|
+
|
263
238
|
# :call-seq:
|
264
239
|
# JiakResource.put(JiakResource,opts={}) -> JiakResource
|
265
240
|
#
|
@@ -276,7 +251,7 @@ module RiakRest
|
|
276
251
|
def put(resource,opts={})
|
277
252
|
opts[:return] = :object
|
278
253
|
resource.jiak.object = jiak.server.store(resource.jiak.object,opts)
|
279
|
-
resource.
|
254
|
+
resource.jiak_convenience
|
280
255
|
resource
|
281
256
|
end
|
282
257
|
|
@@ -450,37 +425,6 @@ module RiakRest
|
|
450
425
|
end
|
451
426
|
end
|
452
427
|
|
453
|
-
# :call-seq:
|
454
|
-
# copy(opts={}) -> JiakResource
|
455
|
-
#
|
456
|
-
# Copies a JiakResource, resetting values passed as options. Valid
|
457
|
-
# options on copy are those mandatory to create a JiakResource:
|
458
|
-
# <code>:server</code>, <code>:group</code>, and
|
459
|
-
# <code>:data_class</code>, and optional auto flags
|
460
|
-
# <code>auto_post</code> and <code>auto_update</code>.
|
461
|
-
#
|
462
|
-
def copy(opts={})
|
463
|
-
valid = [:server,:group,:data_class,:auto_post,:auto_update]
|
464
|
-
err = opts.select {|k,v| !valid.include?(k)}
|
465
|
-
unless err.empty?
|
466
|
-
raise JiakResourceException, "unrecognized options: #{err.keys}"
|
467
|
-
end
|
468
|
-
|
469
|
-
opts[:server] ||= jiak.server.uri
|
470
|
-
opts[:group] ||= jiak.bucket.name
|
471
|
-
opts[:data_class] ||= jiak.bucket.data_class
|
472
|
-
opts[:auto_post] ||= auto_post?
|
473
|
-
opts[:auto_update] ||= auto_update?
|
474
|
-
Class.new do
|
475
|
-
include JiakResource
|
476
|
-
server opts[:server]
|
477
|
-
group opts[:group]
|
478
|
-
data_class opts[:data_class]
|
479
|
-
auto_post opts[:auto_post]
|
480
|
-
auto_update opts[:auto_update]
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
428
|
# :call-seq:
|
485
429
|
# JiakResource.do_auto_update(resource) -> JiakResource or nil
|
486
430
|
#
|
@@ -506,6 +450,10 @@ module RiakRest
|
|
506
450
|
end
|
507
451
|
@jiak = Struct.new(:server,:uri,:group,:data,:bucket,
|
508
452
|
:auto_post,:auto_update).new
|
453
|
+
@jiak.data = JiakDataFields.create
|
454
|
+
@jiak.group = self.name.split('::').last.downcase
|
455
|
+
@jiak.bucket = JiakBucket.new(@jiak.group,@jiak.data)
|
456
|
+
|
509
457
|
@jiak.auto_post = false
|
510
458
|
@jiak.auto_update = false
|
511
459
|
end
|
@@ -540,12 +488,12 @@ module RiakRest
|
|
540
488
|
self.class.post(self)
|
541
489
|
end
|
542
490
|
end
|
543
|
-
|
491
|
+
jiak_convenience
|
544
492
|
end
|
545
493
|
|
546
494
|
# Public method as a by-product of implementation. No harm done in calling
|
547
495
|
# this method, as it will just repeat assignments already done.
|
548
|
-
def
|
496
|
+
def jiak_convenience # :nodoc:
|
549
497
|
@jiak.bucket = @jiak.object.bucket
|
550
498
|
@jiak.key = @jiak.object.key
|
551
499
|
@jiak.data = @jiak.object.data
|
@@ -586,7 +534,7 @@ module RiakRest
|
|
586
534
|
# for options.
|
587
535
|
def put(opts={})
|
588
536
|
@jiak.object = (self.class.put(self,opts)).jiak.object
|
589
|
-
|
537
|
+
jiak_convenience
|
590
538
|
self
|
591
539
|
end
|
592
540
|
|
@@ -598,7 +546,7 @@ module RiakRest
|
|
598
546
|
# options.
|
599
547
|
def post(opts={})
|
600
548
|
@jiak.object = (self.class.post(self,opts)).jiak.object
|
601
|
-
|
549
|
+
jiak_convenience
|
602
550
|
self
|
603
551
|
end
|
604
552
|
|
@@ -610,7 +558,7 @@ module RiakRest
|
|
610
558
|
# options.
|
611
559
|
def update(opts={})
|
612
560
|
@jiak.object = (self.class.update(self,opts)).jiak.object
|
613
|
-
|
561
|
+
jiak_convenience
|
614
562
|
self
|
615
563
|
end
|
616
564
|
alias :push :update
|
data/lib/riakrest.rb
CHANGED
@@ -21,118 +21,39 @@ $:.unshift(dirname) unless
|
|
21
21
|
$:.include?(dirname) ||
|
22
22
|
$:.include?(File.expand_path(dirname))
|
23
23
|
|
24
|
-
# RiakRest provides structured, RESTful interaction with a Riak document
|
25
|
-
# store. In Riak parlance,
|
26
|
-
# provides two levels of interaction: Core Client and
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# use. But we'll show the Core Client first since Resource is built on top of
|
30
|
-
# it.
|
24
|
+
# RiakRest provides structured, RESTful interaction with a Riak document data
|
25
|
+
# store. In Riak parlance, the HTTP/JSON interface to a Riak cluster is called
|
26
|
+
# Jiak. RiakRest provides two levels of Jiak interaction: Core Client and
|
27
|
+
# Resource. Core Client works directly with the Jiak level, whereas Resource is
|
28
|
+
# a resource-oriented abstraction on top of Core Client.
|
31
29
|
#
|
32
|
-
# ===
|
33
|
-
# Primary Jiak constructs are represented by core Jiak classes:
|
34
|
-
# JiakClient :: Client used to make Jiak store, get, delete, and other calls.
|
35
|
-
# JiakBucket :: Bucket name and the data class stored in the bucket.
|
36
|
-
# JiakSchema :: Schema used by a Jiak server bucket.
|
37
|
-
# JiakData :: Class to define user data to be stored on a Jiak server.
|
38
|
-
# JiakObject :: Jiak object wrapper that includes the user-defined data.
|
39
|
-
# JiakLink :: Jiak link objects for associations between Jiak server data.
|
40
|
-
# QueryLink :: Link objects to query Jiak link associations.
|
41
|
-
#
|
42
|
-
# ====Example Usage
|
43
|
-
# This example works at the Jiak core layer. See the Resource example below for
|
44
|
-
# an abstraction layered on top of this core.
|
45
|
-
# <code>
|
46
|
-
# require 'riakrest'
|
47
|
-
# include RiakRest
|
48
|
-
# </code>
|
49
|
-
# Create a simple class to hold Person data.
|
50
|
-
# <code>
|
51
|
-
# Person = JiakDataHash.create(:name,:age)
|
52
|
-
# </code>
|
53
|
-
# Create a client, a bucket to hold the data, and set the bucket schema for
|
54
|
-
# structured interaction.
|
55
|
-
# <code>
|
56
|
-
# client = JiakClient.new("http://localhost:8002/jiak")
|
57
|
-
# bucket = JiakBucket.new('person',Person)
|
58
|
-
# client.set_schema(bucket)
|
59
|
-
# </code>
|
60
|
-
# Wrap a Person data object in a JiakObject and store it. Check the data on the
|
61
|
-
# server to see it's really there.
|
62
|
-
# <code>
|
63
|
-
# remy = client.store(JiakObject.new(:bucket => bucket,
|
64
|
-
# :data => Person.new(:name => "remy",
|
65
|
-
# :age => 10)),
|
66
|
-
# :object => true)
|
67
|
-
# puts client.get(bucket,remy.key).data.name # => "remy"
|
68
|
-
# </code>
|
69
|
-
# Change the data via accessors and update. Again, we print the server value.
|
70
|
-
# <code>
|
71
|
-
# remy.data.name # => "remy"
|
72
|
-
# remy.data.name = "Remy"
|
73
|
-
# client.store(remy)
|
74
|
-
# puts client.get(bucket,remy.key).data.name # => "Remy"
|
75
|
-
# </code>
|
76
|
-
# Let's add another person and a link between them.
|
77
|
-
# <code>
|
78
|
-
# callie = client.store(JiakObject.new(:bucket => bucket,
|
79
|
-
# :data => Person.new(:name => "Callie",
|
80
|
-
# :age => 12)),
|
81
|
-
# :object => true)
|
82
|
-
# remy << JiakLink.new(bucket,callie.key,'sister')
|
83
|
-
# client.store(remy)
|
84
|
-
# </code>
|
85
|
-
# Now we can get callie as the sister of remy:
|
86
|
-
# <code>
|
87
|
-
# sisters = client.query(bucket,remy.key,QueryLink.new(bucket,'sister'),Person)
|
88
|
-
# sisters[0].eql?(callie) # => true
|
89
|
-
# </code>
|
90
|
-
# Finally, we'll delete the objects on the way out the door.
|
91
|
-
# <code>
|
92
|
-
# client.delete(bucket,remy.key)
|
93
|
-
# client.delete(bucket,callie.key)
|
94
|
-
# </code>
|
95
|
-
#
|
96
|
-
# ===Resource Interaction
|
97
|
-
# Much of the above code can be abstracted into resource-based
|
98
|
-
# interaction. RiakRest provides a module JiakResource that allows you to
|
99
|
-
# create resource objects that encapsulate a lot of the cruft of core client
|
100
|
-
# interaction. We'll do the same steps as above using resources.
|
101
|
-
# <code>
|
30
|
+
# ===Example
|
102
31
|
# require 'riakrest'
|
103
32
|
# include RiakRest
|
104
|
-
#
|
105
|
-
#
|
106
|
-
# PersonData.keygen :name
|
107
|
-
#
|
108
|
-
# class Person
|
33
|
+
#
|
34
|
+
# class People
|
109
35
|
# include JiakResource
|
110
|
-
# server
|
111
|
-
#
|
112
|
-
#
|
113
|
-
# auto_post true
|
114
|
-
# auto_update true
|
36
|
+
# server 'http://localhost:8002/jiak'
|
37
|
+
# jattr_accessor :name, :age
|
38
|
+
# auto_manage
|
115
39
|
# end
|
116
|
-
#
|
117
|
-
# remy = Person.new(:name => 'remy',:age => 10) # (auto-post)
|
118
|
-
# puts remy.name # => "remy" (auto-update)
|
119
|
-
#
|
120
|
-
# puts Person.get('remy').name # => "remy" (from Jiak server)
|
121
|
-
# puts Person.get('remy').age # => 10 (from Jiak server)
|
122
40
|
#
|
123
|
-
# remy.age
|
124
|
-
#
|
41
|
+
# remy = People.new(:name => 'Remy',:age => 10) # (auto-post)
|
42
|
+
# remy.age = 11 # (auto-update)
|
125
43
|
#
|
126
|
-
# callie =
|
44
|
+
# callie = People.new(:name => 'Callie', :age => 13)
|
127
45
|
# remy.link(callie,'sister')
|
128
46
|
#
|
129
|
-
# sisters = remy.query(
|
130
|
-
#
|
47
|
+
# sisters = remy.query(People,'sister')
|
48
|
+
# sisters[0].eql?(callie) # => true
|
131
49
|
#
|
132
50
|
# remy.delete
|
133
51
|
# callie.delete
|
134
|
-
#
|
135
|
-
#
|
52
|
+
#
|
53
|
+
# ===Core Client
|
54
|
+
# See JiakClient for Core Client example.
|
55
|
+
#
|
56
|
+
# Go forth and Riak!
|
136
57
|
module RiakRest
|
137
58
|
version_file = File.join(File.dirname(__FILE__),"..","VERSION")
|
138
59
|
VERSION = IO.read(version_file).chomp
|
@@ -140,7 +61,7 @@ module RiakRest
|
|
140
61
|
# Convenience method for checking validity of method options. If any of the
|
141
62
|
# options in opt are not in valid, raise the exception with the invalid
|
142
63
|
# options in the message.
|
143
|
-
def check_opts(opts,valid,exception)
|
64
|
+
def check_opts(opts,valid,exception) # :nodoc:
|
144
65
|
err = opts.select {|k,v| !valid.include?(k)}
|
145
66
|
unless err.empty?
|
146
67
|
raise exception, "unrecognized options: #{err.keys}"
|
@@ -153,16 +74,16 @@ require 'riakrest/core/exceptions'
|
|
153
74
|
require 'riakrest/core/jiak_bucket'
|
154
75
|
require 'riakrest/core/jiak_client'
|
155
76
|
require 'riakrest/core/jiak_data'
|
77
|
+
require 'riakrest/core/jiak_data_fields'
|
156
78
|
require 'riakrest/core/jiak_link'
|
157
79
|
require 'riakrest/core/jiak_object'
|
158
80
|
require 'riakrest/core/jiak_schema'
|
159
81
|
require 'riakrest/core/query_link'
|
160
82
|
|
161
|
-
require 'riakrest/data/jiak_data_hash'
|
162
83
|
require 'riakrest/resource/jiak_resource'
|
163
84
|
|
164
85
|
# Extend Array with convenience methods for comparing array contents.
|
165
|
-
class Array
|
86
|
+
class Array # :nodoc:
|
166
87
|
# Compare arrays for same elements regardless of order.
|
167
88
|
def same_elements?(arr)
|
168
89
|
raise ArgumentError unless arr.is_a?(Array)
|
@@ -1,53 +1,43 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
2
|
|
3
|
+
F1F2 = JiakDataFields.create :f1, :f2
|
4
|
+
G1 = JiakDataFields.create :g1
|
5
|
+
|
3
6
|
describe "JiakBucket" do
|
4
7
|
before do
|
5
8
|
@name = 'bucket_name'
|
6
|
-
@data_class =
|
7
|
-
@params = {:reads => 1, :writes => 2, :durable_writes => 3, :waits => 4}
|
9
|
+
@data_class = F1F2
|
8
10
|
@bucket = JiakBucket.new(@name,@data_class)
|
9
11
|
end
|
10
12
|
|
11
13
|
it "should respond to" do
|
12
|
-
@bucket.should respond_to(:name,:data_class,:
|
13
|
-
@bucket.should respond_to(:name=,:data_class
|
14
|
+
@bucket.should respond_to(:name,:data_class,:schema)
|
15
|
+
@bucket.should respond_to(:name=,:data_class=)
|
14
16
|
@bucket.should respond_to(:eql?)
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should initialize with name and data class" do
|
18
20
|
@bucket.name.should eql @name
|
19
21
|
@bucket.data_class.should eql @data_class
|
20
|
-
@bucket.params.should be_empty
|
21
22
|
end
|
22
23
|
|
23
|
-
it "should initialize with name
|
24
|
-
bucket = JiakBucket.new(@name,@data_class
|
24
|
+
it "should initialize with name and data class" do
|
25
|
+
bucket = JiakBucket.new(@name,@data_class)
|
25
26
|
bucket.name.should eql @name
|
26
27
|
bucket.data_class.should eql @data_class
|
27
|
-
bucket.params.should have_exactly(4).items
|
28
|
-
@params.each {|k,v| bucket.params[k].should == @params[k]}
|
29
|
-
|
30
|
-
@params.delete(:writes)
|
31
|
-
bucket = JiakBucket.new(@name,@data_class,@params)
|
32
|
-
bucket.params.should have_exactly(3).items
|
33
|
-
bucket.params[:waits].should == @params[:waits]
|
34
28
|
end
|
35
29
|
|
36
|
-
it "should update the name
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
it "should update the name and data class" do
|
31
|
+
name = 'new_bucket_name'
|
32
|
+
@bucket.name = name
|
33
|
+
@bucket.name.should eql name
|
40
34
|
|
41
|
-
data_class =
|
35
|
+
data_class = G1
|
42
36
|
@bucket.data_class = data_class
|
43
37
|
@bucket.data_class.should eql data_class
|
44
|
-
|
45
|
-
@bucket.params.should be_empty
|
46
|
-
@bucket.params = @params
|
47
|
-
@bucket.params.should eql @params
|
48
38
|
end
|
49
39
|
|
50
|
-
it "should validate name
|
40
|
+
it "should validate name and data class" do
|
51
41
|
empty_name = lambda {JiakBucket.new("",@data_class)}
|
52
42
|
empty_name.should raise_error(JiakBucketException,/Name.*empty/)
|
53
43
|
|
@@ -62,15 +52,6 @@ describe "JiakBucket" do
|
|
62
52
|
|
63
53
|
bad_data_class = lambda {@bucket.data_class = Hash}
|
64
54
|
bad_data_class.should raise_error(JiakBucketException,/JiakData/)
|
65
|
-
|
66
|
-
params = @params
|
67
|
-
params.delete(:writes)
|
68
|
-
params[:write] = 2
|
69
|
-
bad_params = lambda {JiakBucket.new(@name,@data_class,params)}
|
70
|
-
bad_params.should raise_error(JiakBucketException,/params/)
|
71
|
-
|
72
|
-
bad_params = lambda {@bucket.params = params}
|
73
|
-
bad_params.should raise_error(JiakBucketException,/params/)
|
74
55
|
end
|
75
56
|
|
76
57
|
it "should provide the schema for the data class" do
|
@@ -84,20 +65,9 @@ describe "JiakBucket" do
|
|
84
65
|
bucket = JiakBucket.new(@name.upcase,@data_class)
|
85
66
|
bucket.should_not eql @bucket
|
86
67
|
|
87
|
-
data_class =
|
68
|
+
data_class = G1
|
88
69
|
bucket = JiakBucket.new(@name,data_class)
|
89
70
|
bucket.should_not eql @bucket
|
90
|
-
|
91
|
-
bucket = JiakBucket.new(@name,@data_class,@params)
|
92
|
-
bucket.should_not eql @bucket
|
93
|
-
|
94
|
-
@bucket.params = @params
|
95
|
-
bucket.should eql @bucket
|
96
|
-
|
97
|
-
params = {:reads => @params[:reads]+1}
|
98
|
-
bucket_1 = JiakBucket.new(@name,@data_class,@params)
|
99
|
-
bucket_2 = JiakBucket.new(@name,@data_class,params)
|
100
|
-
bucket_1.should_not eql bucket_2
|
101
71
|
end
|
102
72
|
|
103
73
|
end
|