riakrest 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.1.5 2009-12-11
2
+ - Added POV processing.
3
+ - Refactored jattr_* to attr_*.
4
+ - Added opts to query, which forced steps arg to be an explicit array.
5
+ - Changes to examples for web site.
6
+
1
7
  === 0.1.2 2009-11-29
2
8
  - Add wide open schemas.
3
9
  - Add wild card schema arrays.
data/README.rdoc CHANGED
@@ -1,43 +1,43 @@
1
- = RiakRest
1
+ = RiakREST
2
2
 
3
- http://github.com/wcpr/riakrest
3
+ More information available at RiakREST[http://riakrest.com/].
4
4
 
5
- == DESCRIPTION:
5
+ == Description:
6
6
 
7
- RiakRest provides structured, RESTful interaction with a Riak document
8
- store.
7
+ RiakREST is a Ruby library providing structured, RESTful interaction with
8
+ Riak[http://riak.basho.com], an open-source document datastore.
9
9
 
10
- == RIAK:
10
+ == Riak:
11
11
 
12
12
  Riak[http://riak.basho.com] is an open-source project developed and maintained
13
13
  by the fine folks at Basho[http://www.basho.com] Technologies. Riak combines a
14
14
  decentralized key-value store, a flexible map/reduce engine, and a friendly
15
15
  HTTP/JSON query interface to provide a database ideally suited for Web
16
- applications. RiakRest interacts with the HTTP/JSON query interface, which is
17
- called Jiak.
16
+ applications.
18
17
 
19
- == SYNOPSIS:
18
+ == RiakREST
20
19
 
21
- RiakRest provides structured, RESTful interaction with the HTTP/JSON interface
22
- of a Riak[http://riak.basho.com] document data store. RiakRest provides two
23
- levels of interaction: Core Client and Resource. Core Client works at the Jiak
24
- level and exposes Jiak internals. JiakResource is an abstraction built on top
25
- of the Core Client that gives a true RESTful feel.
20
+ RiakREST provides Ruby interaction with Jiak, the HTTP/JSON interface to a Riak
21
+ cluster, through two different levels of Jiak interaction: Core Client and
22
+ Resource. Core Client works at the Jiak level and mirrors Jiak internals,
23
+ whereas, Resource is an abstraction built on top of the Core Client that
24
+ gives a simplier, RESTful feel.
26
25
 
27
- == REQUIREMENTS:
26
+ == Requirements:
28
27
 
29
- RestClient is used for REST server interaction.
28
+ RestClient (Ruby gem rest-client) is used for RESTful server interaction.
30
29
 
31
30
  JSON is used for data exchange.
32
31
 
33
- Riak[http://riak.basho.com] provides the HTTP/JSON Jiak interface and data
32
+ Riak[http://riak.basho.com] provides the runs the server cluser and provides
33
+ the Jiak HTTP/JSON interface.
34
34
  store.
35
35
 
36
- == INSTALL:
36
+ == Install:
37
37
 
38
38
  sudo gem install riakrest
39
39
 
40
- == EXAMPLE
40
+ == Example
41
41
  require 'riakrest'
42
42
  include RiakRest
43
43
 
@@ -45,22 +45,32 @@ sudo gem install riakrest
45
45
  include JiakResource
46
46
  server 'http://localhost:8002/jiak'
47
47
  jattr_accessor :name, :age
48
- auto_manage
49
48
  end
50
49
 
51
- remy = People.new(:name => 'Remy',:age => 10) # (auto-post)
52
- remy.age = 11 # (auto-update)
50
+ # Created and store a resource.
51
+ remy = Person.new(:name => 'Remy',:age => 10)
52
+ remy.post
53
+
54
+ # Change and store
55
+ remy.age = 11
56
+ remy.put
53
57
 
54
- callie = People.new(:name => 'Callie', :age => 13)
58
+ # Create another resource
59
+ callie = Person.new(:name => 'Callie', :age => 13)
60
+ callie.post
61
+
62
+ # Add a link from remy to callie tagged as 'sister'
55
63
  remy.link(callie,'sister')
64
+ remy.put
56
65
 
57
- sisters = remy.query(People,'sister')
66
+ # Retrieve sister via link
67
+ sisters = remy.query([Person,'sister'])
58
68
  puts sisters[0].eql?(callie) # => true
59
69
 
60
70
  remy.delete
61
71
  callie.delete
62
72
 
63
- == LICENSE:
73
+ == License:
64
74
 
65
75
  Copyright (c) 2009 Paul Rogers, DingoSky. See LICENSE for details.
66
76
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.5
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/example_helper.rb'
2
+
3
+ # Simple resource set to auto-manage instances. Auto-manage does both auto-post
4
+ # and auto-update.
5
+ class Person
6
+ include JiakResource
7
+ server SERVER_URI
8
+ attr_accessor :name, :age
9
+ keygen { name }
10
+ auto_manage
11
+ end
12
+
13
+ # Convenience method for showing results
14
+ def show_jiak_values
15
+ rsrc = Person.get('remy')
16
+ puts "name:#{rsrc.name}, age:#{rsrc.age}"
17
+ end
18
+
19
+ # Create resource. Auto-manage auto-posts the create.
20
+ remy = Person.new(:name => 'remy', :age => 10)
21
+ show_jiak_values # => remy, 10
22
+
23
+ # Changes are auto-updated
24
+ remy.name = "Remy"
25
+ show_jiak_values # => Remy, 10
26
+ remy.age = 12
27
+ show_jiak_values # => Remy, 12
28
+
29
+ # Auto-update can be set at class and instance level
30
+ Person.auto_update false
31
+ remy.auto_update = true
32
+ remy.age = 10
33
+ show_jiak_values # => Remy, 10
34
+
35
+ # Instance level setting overrides class level setting
36
+ Person.auto_update true
37
+ remy.auto_update = false
38
+ remy.age = 12
39
+ show_jiak_values # => Remy, 10
40
+ remy.update
41
+ show_jiak_values # => Remy, 12
42
+
43
+ # Due to class level interaction, set instance level to nil to get class level
44
+ remy.auto_update = nil
45
+ remy.age = 10
46
+ show_jiak_values # => Remy, 10
47
+
48
+ # Clean-up
49
+ remy.delete
50
+
51
+
@@ -1,43 +1,60 @@
1
1
  require File.dirname(__FILE__) + '/example_helper.rb'
2
2
 
3
- class People
3
+ # Simple resource used to show auto-updating of links.
4
+ class Person
4
5
  include JiakResource
5
6
  server SERVER_URI
6
- jattr_accessor :name, :age
7
+ attr_accessor :name, :age
7
8
  keygen { name.downcase }
8
9
  auto_post
9
10
  end
10
11
 
11
- remy = People.new(:name => 'remy', :age => 10)
12
- callie = People.new(:name => 'Callie', :age => 12)
12
+ # Convenience method for checking number of links
13
+ def check_num_links(rsrc,tag,expect)
14
+ num = rsrc.query([Person,tag]).size
15
+ puts " #{expect}? #{num == expect}"
16
+ end
17
+
18
+ # Create resources. (Auto-posted)
19
+ remy = Person.new(:name => 'remy', :age => 10)
20
+ callie = Person.new(:name => 'Callie', :age => 12)
13
21
 
22
+ # Add links. Class-level auto-post does not trigger auto-update.
14
23
  remy.link(callie,'sister')
15
- puts remy.query(People,'sister').size # => 0
24
+ check_num_links(remy,'sister',0) # => true
16
25
  remy.update
17
- puts remy.query(People,'sister').size # => 1
26
+ check_num_links(remy,'sister',1) # => true
18
27
  remy.remove_link(callie,'sister')
28
+ remy.update
29
+ check_num_links(remy,'sister',0) # => true
19
30
 
20
- People.auto_update true
31
+ # Turn on class level auto-update.
32
+ Person.auto_update true
21
33
  remy.link(callie,'sibling')
22
- puts remy.query(People,'sibling').size # => 1
34
+ check_num_links(remy,'sibling',1) # => true
23
35
  remy.remove_link(callie,'sibling')
24
36
 
37
+ # Instance level auto-update settings.
25
38
  callie.auto_update = false
26
39
  callie.link(remy,'sibling')
27
- puts callie.query(People,'sibling').size # => 0
40
+ check_num_links(callie,'sibling',0) # => true
28
41
  callie.update
29
- puts callie.query(People,'sibling').size # => 1
42
+ check_num_links(callie,'sibling',1) # => true
30
43
  callie.remove_link(remy,'sibling')
31
44
 
32
- People.auto_update false
45
+ # Another permutation of class and instance level auto-update settings.
46
+ Person.auto_update false
33
47
  remy.auto_update = true
34
48
  callie.auto_update = nil
49
+
50
+ # bi_link create links in both directions.
35
51
  remy.bi_link(callie,'sisters')
36
- puts remy.query(People,'sisters').size # => 1
37
- puts callie.query(People,'sisters').size # => 0
52
+ check_num_links(remy,'sisters',1) # => true
53
+ check_num_links(callie,'sisters',0) # => true
38
54
  callie.update
39
- puts callie.query(People,'sisters').size # => 1
55
+ check_num_links(callie,'sisters',1) # => true
40
56
 
57
+ # Clean-up
41
58
  remy.delete
42
59
  callie.delete
43
60
 
@@ -1,34 +1,57 @@
1
1
  require File.dirname(__FILE__) + '/example_helper.rb'
2
2
 
3
- class PeopleData
3
+ # Simple JiakData class with a couple of attributes
4
+ class PersonData
4
5
  include JiakData
5
- jattr_accessor :name, :age
6
+ attr_accessor :name, :age
6
7
  end
7
8
 
8
9
  client = JiakClient.new(SERVER_URI)
9
- bucket = JiakBucket.new('people',PeopleData)
10
+ bucket = JiakBucket.new('people',PersonData)
11
+
12
+ puts bucket.name # => 'people'
13
+ puts bucket.data_class # => PeopleData
14
+ puts bucket.data_class.schema # => JiakSchema of data
15
+ puts bucket.schema # => Same as above
16
+
17
+ # The default schema for a Riak bucket is the WIDE_OPEN schema.
18
+ puts client.schema(bucket) # => JiakSchema of server bucket.
10
19
  client.set_schema(bucket)
20
+ puts client.schema(bucket) # => Server schema now data schema
11
21
 
22
+ # Create and store Jiak objects. Keys are server generated. JiakObjects with
23
+ # Riak context are returned.
12
24
  remy = client.store(JiakObject.new(:bucket => bucket,
13
- :data => PeopleData.new(:name => "remy",
25
+ :data => PersonData.new(:name => "remy",
14
26
  :age => 10)),
15
27
  :return => :object)
16
28
  callie = client.store(JiakObject.new(:bucket => bucket,
17
- :data => PeopleData.new(:name => "Callie",
29
+ :data => PersonData.new(:name => "Callie",
18
30
  :age => 12)),
19
31
  :return => :object)
20
32
 
21
- puts client.get(bucket,remy.key).data.name # => "remy"
33
+ puts remy.key # => server generated key
34
+ puts remy.data # => PersonData
35
+ puts remy.data.name # => remy
36
+ puts remy.data.age # => 10
22
37
 
38
+ # Change data and show server value
23
39
  remy.data.name = "Remy"
24
- remy << JiakLink.new(bucket,callie.key,'sister')
25
40
  client.store(remy)
41
+ puts client.get(bucket,remy.key).data.name # => Remy
26
42
 
27
- puts client.get(bucket,remy.key).data.name # => "Remy"
43
+ # Add a link from remy to callie tagged as sister, and show links
44
+ remy << JiakLink.new(bucket,callie.key,'sister')
45
+ client.store(remy)
46
+ puts remy.links # => JiakLink
28
47
 
48
+ # Follow the sister link and test that callie is in the returned array
29
49
  sisters = client.walk(bucket,remy.key,
30
- QueryLink.new(bucket,'sister'),PeopleData)
31
- puts sisters[0].eql?(callie) # => true
50
+ QueryLink.new(bucket,'sister'),PersonData)
51
+ puts sisters.include?(callie) # => true
52
+ puts sisters.size # => 1
53
+ puts sisters[0].data.name # => "Callie"
32
54
 
55
+ # Clean-up
33
56
  client.delete(bucket,remy.key)
34
57
  client.delete(bucket,callie.key)
@@ -1,27 +1,44 @@
1
1
  require File.dirname(__FILE__) + '/example_helper.rb'
2
2
 
3
- class People
3
+ # Simple JiakResource with a couple of attributes
4
+ class Person
4
5
  include JiakResource
5
6
  server SERVER_URI
6
- jattr_accessor :name, :age
7
+ attr_accessor :name, :age
7
8
  keygen {name.downcase}
8
- auto_manage
9
9
  end
10
10
 
11
- remy = People.new(:name => 'Remy',:age => 10) # (auto-post)
12
- puts remy.name # => "Remy"
11
+ # Convenience method for showing results
12
+ def show_jiak_values
13
+ rsrc = Person.get('remy')
14
+ puts "name:#{rsrc.name}, age:#{rsrc.age}"
15
+ end
16
+
17
+ # Created and store a resource.
18
+ remy = Person.new(:name => 'Remy',:age => 10)
19
+ puts "name:#{remy.name}, age:#{remy.age}" # => Remy, 10
20
+ remy.post
21
+ show_jiak_values # => Remy, 10
13
22
 
14
- puts People.get('remy').name # => "Remy" (from Jiak server)
15
- puts People.get('remy').age # => 10 (from Jiak server)
23
+ # Change and store
24
+ remy.age = 11
25
+ remy.put
26
+ show_jiak_values # => Remy, 11
16
27
 
17
- remy.age = 11 # (auto-update)
18
- puts People.get('remy').age # => 11 (from Jiak server)
28
+ # Create another resource
29
+ callie = Person.new(:name => 'Callie', :age => 13)
30
+ callie.post
19
31
 
20
- callie = People.new(:name => 'Callie', :age => 13)
32
+ # Add a link from remy to callie tagged as 'sister'
21
33
  remy.link(callie,'sister')
34
+ remy.put
22
35
 
23
- sisters = remy.query(People,'sister')
24
- puts sisters[0].eql?(callie) # => true
36
+ # Retrieve sister via link
37
+ sisters = remy.query([Person,'sister'])
38
+ puts sisters.include?(callie) # => true
39
+ puts sisters.size # => 1
40
+ puts sisters[0].name # => "Callie"
25
41
 
42
+ # Clean-up
26
43
  remy.delete
27
44
  callie.delete
@@ -0,0 +1,65 @@
1
+ require File.dirname(__FILE__) + '/example_helper.rb'
2
+
3
+ class AB
4
+ include JiakResource
5
+ server SERVER_URI
6
+ group "test"
7
+ attr_accessor :a, :b
8
+ keygen { "k#{a}" }
9
+ end
10
+
11
+ class A
12
+ include JiakResourcePOV
13
+ resource AB
14
+ attr_accessor :a
15
+ end
16
+
17
+ class B
18
+ include JiakResourcePOV
19
+ resource AB
20
+ attr_accessor :b
21
+ end
22
+
23
+ # Store data using AB
24
+ puts "POST ab.a=1, ab.b=2"
25
+ ab = AB.new(:a => 1, :b => 2)
26
+ ab.post
27
+
28
+ # Get POVs using two different mechanisms.
29
+ a = ab.pov(A)
30
+ b = B.get('k1')
31
+ puts "a=#{ab.a}, b=#{ab.b}" # => a=1, b=2
32
+ puts "ab.a and a.a equal 1? #{ab.a == 1 && ab.a == a.a}" # => 1? true
33
+ puts "ab.b and b.b equal 2? #{ab.b == 2 && ab.b == b.b}" # => 2? true
34
+
35
+ # Update data using AB
36
+ puts "\nPUT ab.a=11"
37
+ ab.a = 11
38
+ ab.update
39
+ a.refresh
40
+ b.refresh
41
+ puts "a = #{ab.a}, b = #{ab.b}" # => a=11, b=2
42
+ puts "ab.a and a.a equal 11? #{ab.a == 11 && ab.a == a.a}" # => 11? true
43
+ puts "ab.b and b.b equal 2? #{ab.b == 2 && ab.b == b.b}" # => 2? true
44
+
45
+ # Update data using A
46
+ puts "\nPUT a.a=111"
47
+ a.a = 111
48
+ a.update
49
+ ab.refresh
50
+ b.refresh
51
+ puts "a = #{ab.a}, b = #{ab.b}" # => a=111, b=2
52
+ puts "ab.a and a.a equal 111? #{ab.a == 111 && ab.a == a.a}" # => 111? true
53
+ puts "ab.b and b.b equal 2? #{ab.b == 2 && ab.b == b.b}" # => 2? true
54
+
55
+ # Update data using B
56
+ puts "\nPUT b.b=22"
57
+ b.b = 22
58
+ b.update
59
+ ab.refresh
60
+ a.refresh
61
+ puts "a = #{ab.a}, b = #{ab.b}" # => a=111, b=22
62
+ puts "ab.a and a.a equal 111? #{ab.a == 111 && ab.a == a.a}" # => 111? true
63
+ puts "ab.b and b.b equal 22? #{ab.b == 22 && ab.b == b.b}" # => 22? true
64
+
65
+ ab.delete
data/examples/buoy.rb ADDED
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(__FILE__), 'example_helper.rb')
2
+
3
+ # Primary resource declares server URI, and optional group and keygen, along
4
+ # with full complement of attributes.
5
+ class Buoy
6
+ include JiakResource
7
+
8
+ server SERVER_URI
9
+ group "buoy"
10
+ keygen { name }
11
+
12
+ attr_accessor :name
13
+ attr_accessor :lat, :lon
14
+ attr_accessor :wind_u, :wind_v, :temp_air
15
+ attr_accessor :temp_0, :salt_0
16
+ attr_accessor :temp_10, :salt_10
17
+ attr_accessor :temp_20, :salt_20
18
+ end
19
+
20
+ # POVs declares an existing JiakResource and a subset of attributes, which can
21
+ # be read, write, or both.
22
+ class BuoySurface
23
+ include JiakResourcePOV
24
+ resource Buoy
25
+
26
+ attr_reader :name
27
+ attr_reader :lat, :lon
28
+ attr_accessor :wind_u, :wind_v, :temp_air
29
+ attr_accessor :temp_0, :salt_0
30
+ end
31
+
32
+ class BuoyChain
33
+ include JiakResourcePOV
34
+ resource Buoy
35
+
36
+ attr_accessor :temp_0, :salt_0
37
+ attr_accessor :temp_10, :salt_10
38
+ attr_accessor :temp_20, :salt_20
39
+ end
40
+
41
+ class BuoyWind
42
+ include JiakResourcePOV
43
+ resource Buoy
44
+
45
+ attr_reader :name
46
+ attr_accessor :wind_u, :wind_v
47
+ end
48
+
49
+ class BuoySST
50
+ include JiakResourcePOV
51
+ resource Buoy
52
+
53
+ attr_reader :name, :temp_0
54
+ end
55
+
56
+ # A simple resource for a region of buoys
57
+ class Region
58
+ include JiakResource
59
+ server SERVER_URI
60
+ group 'region'
61
+
62
+ attr_accessor :name
63
+ end
64
+
65
+
66
+ # Some data and a loading mechanism
67
+ M0 = ["M0",[36.83, -121.90], [2.51, 3.12],
68
+ [15.04, 14.98, 14.85, 13.22], [33.34, 33.38, 33.84]]
69
+ M1 = ["M1",[36.75, -122.03], [3.35, 2.42],
70
+ [15.54, 14.43, 14.41, 14.01], [33.37, 33.43, 33.41]]
71
+ M2 = ["M2",[36.70, -122.39], [0.51, 0.44],
72
+ [14.24, 14.03, 13.80, 13.82], [33.20, 33.11, 33.03]]
73
+
74
+ BUOYS = [M0,M1,M2]
75
+
76
+ class BuoyData
77
+ def self.load(m)
78
+ b = {}
79
+ b[:name] = m[0]
80
+ b[:lat],b[:lon] = m[1][0],m[1][1]
81
+ b[:wind_u],b[:wind_v] = m[2][0],m[2][1]
82
+ b[:temp_air],b[:temp_0],b[:temp_10],b[:temp_20] =
83
+ m[3][0],m[3][1],m[3][2],m[3][3]
84
+ b[:salt_0],b[:salt_10],b[:salt_20] = m[4][0],m[4][1],m[4][2]
85
+ b
86
+ end
87
+
88
+ end
89
+
90
+ def show_data(rsrc)
91
+ if(rsrc.class.include?(JiakResourcePOV))
92
+ read_mask = rsrc.class.jiak.read_mask.split(',')
93
+ else
94
+ read_mask = rsrc.class.jiak.bucket.schema.read_mask
95
+ end
96
+ arr = read_mask.map do |field|
97
+ val = rsrc.send(field)
98
+ "#{field.to_s}= #{val}"
99
+ end
100
+ puts " #{rsrc.class}: #{arr.join(',')}"
101
+ end
102
+
@@ -0,0 +1,46 @@
1
+ # buoy.rb contains resource and POV class declarations
2
+ require File.join(File.dirname(__FILE__), 'buoy')
3
+
4
+ # Load buoy data
5
+ buoy0,buoy1,buoy2 =
6
+ BUOYS.map {|m| BuoyData.load(m)}.map {|b| Buoy.new(b)}.each {|m| m.post}
7
+
8
+ # Loaded data for Buoy, BuoySurface, and BuoySST
9
+ buoy0_srf = buoy0.pov(BuoySurface)
10
+ buoy0_sst = buoy0.pov(BuoySST)
11
+ puts "Loaded data"
12
+ show_data(buoy0)
13
+ show_data(buoy0_srf)
14
+ show_data(buoy0_sst)
15
+
16
+ # Change SST via BuoySurface POV
17
+ buoy0_srf.temp_0 = 14.99
18
+ buoy0_srf.update
19
+ buoy0.refresh
20
+ buoy0_sst.refresh
21
+ puts
22
+ puts "SST set to 14.99 via BuoySurface POV"
23
+ show_data(buoy0)
24
+ show_data(buoy0_srf)
25
+ show_data(buoy0_sst)
26
+
27
+ # Create a region and link the 3 buoys
28
+ mbay = Region.new(:name => 'Monterey Bay')
29
+ mbay.post
30
+ [buoy0,buoy1,buoy2].each {|buoy| mbay.link(buoy,'buoy')}
31
+ mbay.update
32
+
33
+ # Get all MBay buoys via query as both Buoy and BuoySST
34
+ buoys = mbay.query([Buoy,'buoy'])
35
+ sst = mbay.query([BuoySST,'buoy'])
36
+ puts
37
+ puts "Check SST of M0 buoy as both Buoy and BuoySST POV"
38
+ m0_buoy = buoys.find {|buoy| buoy.name.eql?('M0')}
39
+ m0_sst = sst.find {|buoy| buoy.name.eql?('M0')}
40
+ show_data(m0_buoy)
41
+ show_data(m0_sst)
42
+ puts " #{m0_buoy.temp_0 == m0_sst.temp_0}" # => true
43
+
44
+ # Clean-up
45
+ [buoy0,buoy1,buoy2,mbay].each {|rsrc| rsrc.delete}
46
+
@@ -5,3 +5,4 @@ require 'riakrest'
5
5
  include RiakRest
6
6
 
7
7
  SERVER_URI = 'http://localhost:8002/jiak'
8
+