riakrest 0.1.6 → 0.1.7

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.
@@ -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
@@ -44,7 +44,7 @@ sudo gem install riakrest
44
44
  class People
45
45
  include JiakResource
46
46
  server 'http://localhost:8002/jiak'
47
- jattr_accessor :name, :age
47
+ attr_accessor :name, :age
48
48
  end
49
49
 
50
50
  # Created and store a resource.
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 = "riak@dingosky.com"
24
- gem.homepage = "http://github.com/wcpr/riakrest"
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.6
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 of which requires conversion
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
- convert :date => lambda{|value| Date.parse(value)}
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
- # It is also possible to use Ruby JSON processing to achieve a similar result;
27
- # however, this is not optimal as the stored Riak data value contains
28
- # Ruby-secific information which may be undesirable to non-Ruby consumers of
29
- # that data.
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
- leap_2012 = DateData2.new(:name => "Leap 2012",
51
- :date => Date.new(2012,02,29))
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 => leap_2012),
72
+ :data => leap_2008),
54
73
  :return => :object)
55
- puts leap_obj.data.date.inspect # => #<Date: 2012-02-29 (etc.)>
74
+ puts leap_obj.data.date.inspect # => #<Date: 2008-02-29 (etc.)>
56
75
 
57
- # JSON payload:
58
- # leap_2008 : {"name":"leap","date":"2008-02-29"}
59
- # leap_2012 : {"name":"leap","date":{"json_class":"Date","date":"2012-02-29"}}
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, one of which requires conversion
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
- convert :birthdate => lambda{|value| Date.parse(value)}
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
- age -= 1 if(now.yday < birthdate.yday)
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
- # Create and post resource, showing birthdate is a Date before and after post.
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
- # :call-seq:
184
- # JiakData.convert(hash) -> nil
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
- unless(@converter.nil?)
209
- @converter.each {|k,blk| jiak[k] = blk.call(jiak[k])}
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.extend(ClassMethods)
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,field|
221
- build[field] = send("#{field}")
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
- # JiakResource.convert(hash)
139
- #
140
- # Specify a hash of optional Procs for converting the data values stored
141
- # in Riak during the process of inflating returned Riak data into
142
- # JiakResource objects. The hash values should be Procs used to convert
143
- # the data attribute specified by the hash key. The Procs must accept one
144
- # argument, the data value actually stored in Riak. The converted result
145
- # will be the actual value of the data field inside the inflated
146
- # JiakResource.
147
- def convert(hash)
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
- convert :date => lambda { |v| Date.parse(v) }
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
- convert :birthdate => lambda{|value| Date.parse(value)}
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.6
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-16 00:00:00 -08:00
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: riak@dingosky.com
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://github.com/wcpr/riakrest
126
+ homepage: http://riakrest.com
127
127
  licenses: []
128
128
 
129
129
  post_install_message: