riakrest 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +41 -0
- data/PostInstall.txt +2 -0
- data/README.rdoc +51 -0
- data/Rakefile +24 -0
- data/examples/auto_update_data.rb +50 -0
- data/examples/auto_update_links.rb +48 -0
- data/examples/basic_client.rb +33 -0
- data/examples/basic_resource.rb +34 -0
- data/examples/json_data_resource.rb +32 -0
- data/examples/linked_resource.rb +113 -0
- data/examples/multiple_resources.rb +43 -0
- data/lib/riakrest/core/exceptions.rb +73 -0
- data/lib/riakrest/core/jiak_bucket.rb +146 -0
- data/lib/riakrest/core/jiak_client.rb +316 -0
- data/lib/riakrest/core/jiak_data.rb +265 -0
- data/lib/riakrest/core/jiak_link.rb +131 -0
- data/lib/riakrest/core/jiak_object.rb +233 -0
- data/lib/riakrest/core/jiak_schema.rb +242 -0
- data/lib/riakrest/core/query_link.rb +156 -0
- data/lib/riakrest/data/jiak_data_hash.rb +182 -0
- data/lib/riakrest/resource/jiak_resource.rb +628 -0
- data/lib/riakrest/version.rb +7 -0
- data/lib/riakrest.rb +164 -0
- data/riakrest.gemspec +38 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/core/exceptions_spec.rb +18 -0
- data/spec/core/jiak_bucket_spec.rb +103 -0
- data/spec/core/jiak_client_spec.rb +358 -0
- data/spec/core/jiak_link_spec.rb +77 -0
- data/spec/core/jiak_object_spec.rb +210 -0
- data/spec/core/jiak_schema_spec.rb +184 -0
- data/spec/core/query_link_spec.rb +128 -0
- data/spec/data/jiak_data_hash_spec.rb +14 -0
- data/spec/resource/jiak_resource_spec.rb +128 -0
- data/spec/riakrest_spec.rb +17 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +12 -0
- data/tasks/rspec.rake +21 -0
- 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
|