riakrest 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -1
- data/README.rdoc +1 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/examples/jiak_client.data.rb +34 -13
- data/examples/jiak_resource_data.rb +64 -4
- data/lib/riakrest/core/jiak_data.rb +52 -29
- data/lib/riakrest/resource/jiak_resource.rb +10 -11
- data/spec/core/jiak_client_spec.rb +3 -1
- data/spec/resource/jiak_resource_spec.rb +3 -1
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
=== 0.1.7 2009-12-17
|
2
|
+
- Added write data conversion.
|
3
|
+
|
1
4
|
=== 0.1.6 2009-12-17
|
2
|
-
- Add method for specifying data conversion in JiakData and JiakResouce.
|
5
|
+
- Add method for specifying read data conversion in JiakData and JiakResouce.
|
3
6
|
- Add testing and examples for data conversion.
|
4
7
|
|
5
8
|
=== 0.1.5 2009-12-11
|
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -20,8 +20,8 @@ Jeweler::Tasks.new do |gem|
|
|
20
20
|
that gives a true RESTful feel.
|
21
21
|
EOS
|
22
22
|
gem.authors = ["Paul Rogers"]
|
23
|
-
gem.email = "
|
24
|
-
gem.homepage = "http://
|
23
|
+
gem.email = "paul@riakrest.com"
|
24
|
+
gem.homepage = "http://riakrest.com"
|
25
25
|
gem.add_dependency('rest-client', '>= 1.0.0')
|
26
26
|
gem.add_dependency('json', '>= 1.1.9')
|
27
27
|
gem.add_development_dependency "rest-client", ">= 1.0.0"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
@@ -1,11 +1,12 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/example_helper.rb'
|
2
2
|
require 'date'
|
3
3
|
|
4
|
-
# JiakData class with a couple of attributes, one
|
4
|
+
# JiakData class with a couple of attributes, one with conversion
|
5
5
|
class DateData
|
6
6
|
include JiakData
|
7
7
|
attr_accessor :name, :date
|
8
|
-
|
8
|
+
|
9
|
+
attr_converter :date => { :read => lambda{|value| Date.parse(value)} }
|
9
10
|
end
|
10
11
|
|
11
12
|
client = JiakClient.new(SERVER_URI)
|
@@ -23,10 +24,28 @@ puts leap_obj.data.date.inspect # => #<Date: 2008-02-29 (etc.)>
|
|
23
24
|
client.delete(bucket,leap_obj.key)
|
24
25
|
|
25
26
|
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
# Alter DateData to store ordinal Date
|
28
|
+
class DateData
|
29
|
+
attr_converter(:date => {
|
30
|
+
:write => lambda {|v| { :year => v.year, :yday => v.yday} },
|
31
|
+
:read => lambda {|v| Date::ordinal(v['year'],v['yday'])} } )
|
32
|
+
end
|
33
|
+
leap_obj = client.store(JiakObject.new(:bucket => bucket,
|
34
|
+
:data => leap_2008),
|
35
|
+
:return => :object)
|
36
|
+
puts leap_obj.data.date.inspect # => #<Date: 2008-02-29 (etc.)>
|
37
|
+
|
38
|
+
# JSON payload
|
39
|
+
# {"name":"Leap 2008","date":{"year":2008,"yday":60}}
|
40
|
+
|
41
|
+
# Clean-up stored object
|
42
|
+
client.delete(bucket,leap_obj.key)
|
43
|
+
|
44
|
+
|
45
|
+
# It is also possible to change the JSON processing of the Ruby Date class to
|
46
|
+
# achieve the same results as above. Given the following changes to the Date
|
47
|
+
# class, the DateData class could be defined as before, but without any
|
48
|
+
# attribute converters.
|
30
49
|
|
31
50
|
# Instrument the Ruby Date class for round-trip JSON processing.
|
32
51
|
class Date
|
@@ -47,16 +66,18 @@ end
|
|
47
66
|
|
48
67
|
bucket = JiakBucket.new('date data',DateData2)
|
49
68
|
|
50
|
-
|
51
|
-
:date => Date.new(
|
69
|
+
leap_2008 = DateData2.new(:name => "Leap 2008",
|
70
|
+
:date => Date.new(2008,02,29))
|
52
71
|
leap_obj = client.store(JiakObject.new(:bucket => bucket,
|
53
|
-
:data =>
|
72
|
+
:data => leap_2008),
|
54
73
|
:return => :object)
|
55
|
-
puts leap_obj.data.date.inspect # => #<Date:
|
74
|
+
puts leap_obj.data.date.inspect # => #<Date: 2008-02-29 (etc.)>
|
56
75
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
76
|
+
# However, this is not optimal as the data stored in Riak now contains
|
77
|
+
# Ruby-secific information which may be undesirable to non-Ruby consumers of
|
78
|
+
# the data. For the code above, the JSON payload contains:
|
79
|
+
#
|
80
|
+
# {"name":"Leap 2008","date":{"json_class":"Date","date":"2008-02-29"}}
|
60
81
|
|
61
82
|
# Clean-up stored object
|
62
83
|
client.delete(bucket,leap_obj.key)
|
@@ -1,23 +1,27 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/example_helper.rb'
|
2
2
|
require 'date'
|
3
3
|
|
4
|
-
# JiakResource with a couple of attributes
|
4
|
+
# JiakResource with a couple of attributes. Store birthdate as ordinal Date.
|
5
5
|
class Person
|
6
6
|
include JiakResource
|
7
7
|
server SERVER_URI
|
8
8
|
attr_accessor :name, :birthdate
|
9
|
-
|
9
|
+
attr_converter :birthdate => { :read => lambda{|value| Date.parse(value)} }
|
10
10
|
keygen {name.downcase}
|
11
11
|
|
12
|
+
# Calculate "human" age from birthdate
|
12
13
|
def age
|
13
14
|
now = DateTime.now
|
14
15
|
age = now.year - birthdate.year
|
15
|
-
|
16
|
+
if((now.month < birthdate.month) or
|
17
|
+
(now.month == birthdate.month and now.day < birthdate.day))
|
18
|
+
age -= 1
|
19
|
+
end
|
16
20
|
age
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
|
-
#
|
24
|
+
# The birthdate attribute is a Date before and after post.
|
21
25
|
remy = Person.new(:name => 'Remy',:birthdate => Date.new(1999,06,26))
|
22
26
|
puts remy.birthdate.inspect # => #<Date: 1999-06-26 (etc.)>
|
23
27
|
puts remy.age # => current age
|
@@ -27,3 +31,59 @@ puts remy.age # => current age
|
|
27
31
|
|
28
32
|
remy.delete
|
29
33
|
|
34
|
+
# JSON payload from the HTTP request and response
|
35
|
+
# {"name":"Remy","birthdate":"1999-06-26"}
|
36
|
+
|
37
|
+
class Person
|
38
|
+
attr_converter(:birthdate => {
|
39
|
+
:write => lambda{|v| {:year => v.year, :yday => v.yday} },
|
40
|
+
:read => lambda{|v| Date::ordinal(v['year'],v['yday'])}})
|
41
|
+
end
|
42
|
+
|
43
|
+
# The same code as previous yields the exact same results.
|
44
|
+
remy = Person.new(:name => 'Remy',:birthdate => Date.new(1999,06,26))
|
45
|
+
puts remy.birthdate.inspect # => #<Date: 1999-06-26 (etc.)>
|
46
|
+
puts remy.age # => current age
|
47
|
+
remy.post
|
48
|
+
puts remy.birthdate.inspect # => #<Date: 1999-06-26 (etc.)>
|
49
|
+
puts remy.age # => current age
|
50
|
+
|
51
|
+
remy.delete
|
52
|
+
|
53
|
+
# JSON payload from the HTTP request and response with ordinal Date structure
|
54
|
+
# {"name":"Remy","birthdate":{"year":1999,"yday":177}}
|
55
|
+
|
56
|
+
|
57
|
+
# It is also possible to change the JSON processing of the Ruby Date class to
|
58
|
+
# achieve the same results as above. Given the following changes to the Date
|
59
|
+
# class, the Person class could be defined as before, but without any attribute
|
60
|
+
# converters.
|
61
|
+
|
62
|
+
# Instrument the Ruby Date class for round-trip JSON processing.
|
63
|
+
class Date
|
64
|
+
def to_json(*args)
|
65
|
+
{ 'json_class' => self.class.name,
|
66
|
+
'date' => to_s
|
67
|
+
}.to_json(*args)
|
68
|
+
end
|
69
|
+
def self.json_create(hash)
|
70
|
+
parse(hash['date'])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Person2
|
75
|
+
include JiakResource
|
76
|
+
server SERVER_URI
|
77
|
+
attr_accessor :name, :birthdate
|
78
|
+
end
|
79
|
+
|
80
|
+
remy = Person2.new(:name => 'Remy',:birthdate => Date.new(1999,06,26))
|
81
|
+
remy.post
|
82
|
+
puts remy.birthdate.inspect # => #<Date: 1999-06-26 (etc.)>
|
83
|
+
|
84
|
+
# However, this is not optimal as the data stored in Riak now contains
|
85
|
+
# Ruby-secific information which may be undesirable to non-Ruby consumers of
|
86
|
+
# the data. For the code above, the JSON payload contains:
|
87
|
+
#
|
88
|
+
# {"name":"Remy","birthdate":{"json_class":"Date","date":"1999-06-26"}}
|
89
|
+
|
@@ -81,6 +81,34 @@ module RiakRest
|
|
81
81
|
writable *fields
|
82
82
|
end
|
83
83
|
|
84
|
+
# :call-seq:
|
85
|
+
# att_converter(hash) -> nil
|
86
|
+
#
|
87
|
+
# Specify a hash of optional Procs for converting data attribute values
|
88
|
+
# during reading and writing data to a Jiak server. Each hash key should
|
89
|
+
# be a data class attribute, with an associated value of a hash
|
90
|
+
# containing a write and/or a read Proc for use in converting data. Each
|
91
|
+
# Procs should accept one argument, the data value actually stored in
|
92
|
+
# Riak.
|
93
|
+
#
|
94
|
+
# ====Example
|
95
|
+
#
|
96
|
+
# A Person data class that stores a Date in ordinal format:
|
97
|
+
#
|
98
|
+
# def PersonData
|
99
|
+
# include JiakData
|
100
|
+
# attr_accessor :name, :birthdate
|
101
|
+
# attr_converter(:birthdate => {
|
102
|
+
# :write => lambda {|v| { :year => v.year, :yday => v.yday} },
|
103
|
+
# :read => lambda {|v| Date::ordinal(v['year'],v['yday'])} } )
|
104
|
+
# end
|
105
|
+
def attr_converter(hash)
|
106
|
+
hash.each do |attr,blks|
|
107
|
+
@read_converter[attr] = blks[:read] if(blks[:read])
|
108
|
+
@write_converter[attr] = blks[:write] if(blks[:write])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
84
112
|
# :call-seq:
|
85
113
|
# allow :f1, ..., :fn -> array
|
86
114
|
# allow [:f1, ..., :fn] -> array
|
@@ -180,33 +208,12 @@ module RiakRest
|
|
180
208
|
define_method(:keygen,&block)
|
181
209
|
end
|
182
210
|
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
# Specify a hash of optional Procs for converting the data values stored
|
187
|
-
# in Riak during the process of inflating returned Riak data into Ruby
|
188
|
-
# objects. The hash values should be Procs used to convert the data
|
189
|
-
# attribute specified by the hash key. The Procs must accept one
|
190
|
-
# argument, the data value actually stored in Riak. The converted result
|
191
|
-
# will be the actual value of the data field inside the inflated Ruby
|
192
|
-
# object.
|
193
|
-
#
|
194
|
-
# ====Example
|
195
|
-
# def PersonData
|
196
|
-
# include JiakData
|
197
|
-
# attr_accessor :name, :birthdate
|
198
|
-
# convert :birthdate => lambda {|val| Date.parse(val)}
|
199
|
-
# end
|
200
|
-
def convert(hash)
|
201
|
-
@converter ||= {}
|
202
|
-
hash.each {|k,blk| @converter[k.to_s] = blk}
|
203
|
-
end
|
204
|
-
|
205
|
-
# Use optional converters to convert returned data values before passing
|
206
|
-
# to the JiakData constructor.
|
211
|
+
# Use optional read converters to convert returned data values before
|
212
|
+
# passing to the JiakData constructor.
|
207
213
|
def jiak_create(jiak) # :nodoc:
|
208
|
-
|
209
|
-
|
214
|
+
read_converter.each do |attr,blk|
|
215
|
+
key = attr.to_s
|
216
|
+
jiak[key] = blk.call(jiak[key])
|
210
217
|
end
|
211
218
|
new(jiak)
|
212
219
|
end
|
@@ -214,11 +221,27 @@ module RiakRest
|
|
214
221
|
end
|
215
222
|
|
216
223
|
def self.included(including_class) # :nodoc:
|
217
|
-
including_class.
|
224
|
+
including_class.instance_eval do
|
225
|
+
extend ClassMethods
|
226
|
+
|
227
|
+
def read_converter
|
228
|
+
@read_converter
|
229
|
+
end
|
230
|
+
@read_converter = {}
|
231
|
+
|
232
|
+
def write_converter
|
233
|
+
@write_converter
|
234
|
+
end
|
235
|
+
@write_converter = {}
|
236
|
+
end
|
218
237
|
|
219
238
|
define_method(:to_jiak) do
|
220
|
-
self.class.schema.write_mask.inject({}) do |build,
|
221
|
-
|
239
|
+
self.class.schema.write_mask.inject({}) do |build,attr|
|
240
|
+
val = send("#{attr}")
|
241
|
+
if(self.class.write_converter[attr])
|
242
|
+
val = self.class.write_converter[attr].call(val)
|
243
|
+
end
|
244
|
+
build[attr] = val
|
222
245
|
build
|
223
246
|
end
|
224
247
|
end
|
@@ -135,17 +135,16 @@ module RiakRest
|
|
135
135
|
end
|
136
136
|
|
137
137
|
# :call-seq:
|
138
|
-
#
|
139
|
-
#
|
140
|
-
# Specify a hash of optional Procs for converting
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
# argument, the data value actually stored in
|
145
|
-
#
|
146
|
-
|
147
|
-
|
148
|
-
jiak.data.convert(hash)
|
138
|
+
# attr_converter(hash)
|
139
|
+
#
|
140
|
+
# Specify a hash of optional Procs for converting data attribute values
|
141
|
+
# during reading and writing data to a Jiak server. Each hash key should
|
142
|
+
# be a data class attribute, with an associated value of a hash
|
143
|
+
# containing a write and/or a read Proc for use in converting data. Each
|
144
|
+
# Procs should accept one argument, the data value actually stored in
|
145
|
+
# Riak.
|
146
|
+
def attr_converter(hash)
|
147
|
+
jiak.data.attr_converter(hash)
|
149
148
|
end
|
150
149
|
|
151
150
|
# :call-seq:
|
@@ -11,7 +11,9 @@ require 'date'
|
|
11
11
|
class DateData
|
12
12
|
include JiakData
|
13
13
|
attr_accessor :name, :date
|
14
|
-
|
14
|
+
attr_converter(:date => {
|
15
|
+
:write => lambda {|v| { :year => v.year, :yday => v.yday} },
|
16
|
+
:read => lambda {|v| Date::ordinal(v['year'],v['yday'])} } )
|
15
17
|
end
|
16
18
|
|
17
19
|
class PersonData
|
@@ -325,7 +325,9 @@ describe "JiakResource data conversion" do
|
|
325
325
|
server SERVER_URI
|
326
326
|
group 'dogs'
|
327
327
|
attr_accessor :name, :birthdate
|
328
|
-
|
328
|
+
attr_converter(:birthdate => {
|
329
|
+
:write => lambda{|v| {:year => v.year, :yday => v.yday} },
|
330
|
+
:read => lambda{|v| Date::ordinal(v['year'],v['yday'])}})
|
329
331
|
keygen { name }
|
330
332
|
auto_manage
|
331
333
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riakrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Rogers
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-17 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -73,7 +73,7 @@ dependencies:
|
|
73
73
|
version: 1.2.9
|
74
74
|
version:
|
75
75
|
description: " RiakRest provides structured, RESTful interaction with\n the HTTP/JSON interface of a Riak[http://riak.basho.com] document data\n store. RiakRest provides two levels of interaction: Core Client and\n Resource. Core Client works at the Jiak level and exposes Jiak\n internals. JiakResource is an abstraction built on top of the Core Client\n that gives a true RESTful feel.\n"
|
76
|
-
email:
|
76
|
+
email: paul@riakrest.com
|
77
77
|
executables: []
|
78
78
|
|
79
79
|
extensions: []
|
@@ -123,7 +123,7 @@ files:
|
|
123
123
|
- spec/spec.opts
|
124
124
|
- spec/spec_helper.rb
|
125
125
|
has_rdoc: true
|
126
|
-
homepage: http://
|
126
|
+
homepage: http://riakrest.com
|
127
127
|
licenses: []
|
128
128
|
|
129
129
|
post_install_message:
|