riakrest 0.1.2 → 0.1.5

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 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
+