riik 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ tags
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ TAGS
20
+ .tddium*
21
+ .tddium
@@ -0,0 +1 @@
1
+ 1.9.3-p0
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ script: "bundle exec rake spec"
@@ -0,0 +1,2 @@
1
+ --markup markdown
2
+ --markup-provider redcarpet
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ # Specify your gem's dependencies in riik.gemspec
4
+ gemspec
@@ -0,0 +1,15 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$}) { "spec" }
3
+ watch(%r{^lib/(.+)\.rb$}) { "spec" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'ctags-bundler' do
8
+ watch(%r{^(app|lib)/.*\.rb$}) { ["lib"] }
9
+ end
10
+
11
+ guard 'yard' do
12
+ watch(%r{app/.+\.rb})
13
+ watch(%r{lib/.+\.rb})
14
+ watch(%r{ext/.+\.c})
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Critical Pair.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,50 @@
1
+ Riik
2
+ ====
3
+
4
+ Lightweight object mapper for Riak.
5
+
6
+ Motivation
7
+ ==========
8
+
9
+ Riik doesn't support everything you would exepct from a full ORM. There
10
+ are no validations, no callbacks, and no error handling, as the primary
11
+ motivation was providing an extremely thin abstraction over RObject
12
+ allowing you to map an objects serialized fields into keys. The
13
+ benefits come from being able to work with a lightweight abstraction
14
+ without dependencies on larger, external gems, such as activesupport and
15
+ activemodel.
16
+
17
+ If you're building an entire site with Riak as the primary data store,
18
+ you should be looking at [Ripple](https://github.com/seancribbs/ripple).
19
+
20
+ If you're looking at building a gem or Ruby application that needs to
21
+ write serialized objects directly to Riak without any overhead, look no
22
+ further.
23
+
24
+ Usage
25
+ =====
26
+
27
+ To define a class:
28
+
29
+ ```ruby
30
+ class Person
31
+ include Riik::Document
32
+
33
+ property :first_name
34
+ property :last_name
35
+ end
36
+ ```
37
+
38
+ To use:
39
+
40
+ ```ruby
41
+ p = Person.new(:first_name => 'Fat', :last_name => 'Mike')
42
+ p.save # => true
43
+ p.destroy # => true
44
+ Person.find(p.key) # => p
45
+ ```
46
+
47
+ License
48
+ =======
49
+
50
+ Riik is Copyright © 2011 Critical Pair. Riik is free software, and may be redistributed under the terms specified in the LICENSE file.
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ require 'bundler/gem_tasks'
6
+ require 'rake'
7
+ require 'rdoc/task'
8
+ require 'rake/clean'
9
+ require 'rubygems/package_task'
10
+ require 'rspec/core/rake_task'
11
+ require 'rdoc'
12
+ require 'yard'
13
+
14
+ include Rake::DSL
15
+
16
+ Bundler::GemHelper.install_tasks
17
+
18
+ RSpec::Core::RakeTask.new do |t|
19
+ t.pattern = 'spec/**/*_spec.rb'
20
+ end
21
+
22
+ YARD::Rake::YardocTask.new do |t|
23
+ t.files = ['lib/**/*.rb']
24
+ t.options = ['--no-private']
25
+ end
26
+
27
+ task :default => [:spec]
@@ -0,0 +1,2 @@
1
+ :tddium:
2
+ :riak: true
@@ -0,0 +1,38 @@
1
+ require 'riik/version'
2
+ require 'riak'
3
+
4
+ # Riik is a lightweight object mapper for Riak.
5
+ #
6
+ # To define a class:
7
+ #
8
+ # ```ruby
9
+ # class Person
10
+ # include Riik::Document
11
+ #
12
+ # property :first_name
13
+ # property :last_name
14
+ # end
15
+ # ```
16
+ #
17
+ # To use:
18
+ #
19
+ # ```ruby
20
+ # p = Person.new(:first_name => 'Fat', :last_name => 'Mike')
21
+ # p.save # => true
22
+ # p.destroy # => true
23
+ # Person.find(p.key) # => p
24
+ # ```
25
+ #
26
+ module Riik
27
+ autoload :Document, 'riik/document'
28
+
29
+ class << self
30
+ def client=(client)
31
+ @client = client
32
+ end
33
+
34
+ def client
35
+ @client ||= Riak::Client.new
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,116 @@
1
+ module Riik
2
+
3
+ # Document is the base object for the Riik ORM. Including it provides
4
+ # the basic functionality for assigning attributes to models,
5
+ # assigning a bucket name, and serializing objects.
6
+ #
7
+ module Document
8
+ autoload :Persistence, 'riik/document/persistence'
9
+ autoload :Finders, 'riik/document/finders'
10
+
11
+ def self.included(base)
12
+ base.send :extend, ClassMethods
13
+
14
+ base.send :include, Finders
15
+ base.send :include, Persistence
16
+ end
17
+
18
+ module ClassMethods
19
+
20
+ # List of model properties that should be assigned from the attributes
21
+ # hash.
22
+ #
23
+ attr_reader :riik_attributes
24
+
25
+ # Create accessors for each of the properties of the model.
26
+ #
27
+ # @private
28
+ #
29
+ def property(attribute)
30
+ @riik_attributes ||= []
31
+ @riik_attributes << attribute
32
+
33
+ attr_accessor attribute
34
+ end
35
+
36
+ # Returns the Riak bucket for this object.
37
+ #
38
+ # @return [Riak::Bucket]
39
+ #
40
+ def bucket
41
+ @bucket ||= Riik.client.bucket(bucket_name)
42
+ end
43
+
44
+ # Returns the bucket name for this object. Override in your class
45
+ # to change.
46
+ #
47
+ # @return [String] bucket name.
48
+ #
49
+ def bucket_name
50
+ self.to_s.gsub(/::/, '_').downcase
51
+ end
52
+ end
53
+
54
+ # Assign model attributes through initialization hash.
55
+ #
56
+ # @param [Hash] attributes
57
+ #
58
+ def initialize(attributes = {})
59
+ attributes.symbolize_keys.each do |key, value|
60
+ if riik_attributes.include?(key)
61
+ instance_variable_set "@#{key}", value
62
+ end
63
+ end
64
+ end
65
+
66
+ # Serialize the attributes of this model.
67
+ #
68
+ # @return [Hash] serialized attributes.
69
+ # @private
70
+ #
71
+ def attributes
72
+ Hash[riik_attributes.zip(riik_attributes.map { |attr| instance_variable_get "@#{attr}" })]
73
+ end
74
+
75
+ # Return the riik attribute list for this class.
76
+ #
77
+ # @return [Array] symbols for each model property.
78
+ # @private
79
+ #
80
+ def riik_attributes
81
+ self.class.riik_attributes
82
+ end
83
+
84
+ # Return the bucket for this class.
85
+ #
86
+ # @return [Riak::Bucket]
87
+ #
88
+ def bucket
89
+ self.class.bucket
90
+ end
91
+
92
+ # Delegate the object key to the Riak object.
93
+ #
94
+ # @return [String]
95
+ #
96
+ def key
97
+ robject.key
98
+ end
99
+
100
+ # Store the current Riak client object.
101
+ #
102
+ attr_accessor :robject
103
+
104
+ # Create or return the current Riak client object.
105
+ #
106
+ # @return [Riak::RObject]
107
+ # @private
108
+ #
109
+ def robject
110
+ @robject ||= Riak::RObject.new(bucket).tap do |object|
111
+ object.content_type = "application/json"
112
+ end
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,40 @@
1
+ module Riik
2
+ module Document
3
+
4
+ # Finders provide methods to find objects in Riak.
5
+ #
6
+ module Finders
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ # Find an object by key.
14
+ #
15
+ # @return [Object] instance of the object, if found, else nil.
16
+ #
17
+ def find(key)
18
+ if robject = get(key)
19
+ self.new(robject.data).tap do |object|
20
+ object.robject = robject
21
+ end
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ # Get the key from Riak.
28
+ #
29
+ # @return [Riak::RObject]
30
+ # @private
31
+ #
32
+ def get(key)
33
+ bucket.get(key)
34
+ end
35
+ private :get
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ module Riik
2
+ module Document
3
+
4
+ # Persistence provides methods for creating and saving documents to
5
+ # Riak.
6
+ #
7
+ module Persistence
8
+ def self.included(base)
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Create a new object from provided attributes.
15
+ #
16
+ # @return [Object] instance of created object.
17
+ #
18
+ def create(attributes = {})
19
+ self.new(attributes).tap do |object|
20
+ object.save
21
+ end
22
+ end
23
+ end
24
+
25
+ # Save the object to Riak.
26
+ #
27
+ # @return [Boolean]
28
+ #
29
+ def save
30
+ robject.data = attributes
31
+ robject.store
32
+ end
33
+
34
+ # Destroy the object in Riak.
35
+ #
36
+ # @return [Boolean]
37
+ #
38
+ def destroy
39
+ robject.delete
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Riik
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+
5
+ require "riik/version"
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.authors = ["Christopher Meiklejohn"]
9
+ gem.email = ["cmeiklejohn@criticalpair.com"]
10
+ gem.description = %q{Lightweight object mapper for Riak.}
11
+ gem.summary = %q{Lightweight object mapper for Riak.}
12
+ gem.homepage = "http://critialpair.com"
13
+
14
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+
18
+ gem.name = "riik"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Riik::VERSION
21
+
22
+ gem.add_dependency('riak-client')
23
+ gem.add_dependency('excon')
24
+
25
+ gem.add_development_dependency('yard')
26
+ gem.add_development_dependency('rdoc')
27
+ gem.add_development_dependency('redcarpet')
28
+
29
+ gem.add_development_dependency('vcr')
30
+ gem.add_development_dependency('webmock')
31
+
32
+ gem.add_development_dependency('rspec')
33
+ gem.add_development_dependency('rake','~> 0.9.2')
34
+
35
+ gem.add_development_dependency('ripple')
36
+
37
+ gem.add_development_dependency('guard')
38
+ gem.add_development_dependency('guard-rspec')
39
+ gem.add_development_dependency('guard-yard')
40
+ gem.add_development_dependency('guard-ctags-bundler')
41
+ end
@@ -0,0 +1,69 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: http://127.0.0.1:8098/
6
+ body:
7
+ headers:
8
+ accept:
9
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
10
+ x-riak-clientid:
11
+ - jmE3aA==
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ vary:
18
+ - Accept
19
+ server:
20
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
21
+ link:
22
+ - </buckets>; rel="riak_kv_wm_buckets",</riak>; rel="riak_kv_wm_buckets",</buckets>;
23
+ rel="riak_kv_wm_index",</buckets>; rel="riak_kv_wm_keylist",</buckets>; rel="riak_kv_wm_link_walker",</riak>;
24
+ rel="riak_kv_wm_link_walker",</mapred>; rel="riak_kv_wm_mapred",</buckets>;
25
+ rel="riak_kv_wm_object",</riak>; rel="riak_kv_wm_object",</ping>; rel="riak_kv_wm_ping",</buckets>;
26
+ rel="riak_kv_wm_props",</stats>; rel="riak_kv_wm_stats"
27
+ date:
28
+ - Tue, 29 Nov 2011 05:43:22 GMT
29
+ content-type:
30
+ - application/json
31
+ content-length:
32
+ - '366'
33
+ body: ! '{"riak_kv_wm_buckets":"/buckets","riak_kv_wm_buckets":"/riak","riak_kv_wm_index":"/buckets","riak_kv_wm_keylist":"/buckets","riak_kv_wm_link_walker":"/buckets","riak_kv_wm_link_walker":"/riak","riak_kv_wm_mapred":"/mapred","riak_kv_wm_object":"/buckets","riak_kv_wm_object":"/riak","riak_kv_wm_ping":"/ping","riak_kv_wm_props":"/buckets","riak_kv_wm_stats":"/stats"}'
34
+ http_version: '1.1'
35
+ - !ruby/struct:VCR::HTTPInteraction
36
+ request: !ruby/struct:VCR::Request
37
+ method: :post
38
+ uri: http://127.0.0.1:8098/riak/riik_person?returnbody=true
39
+ body: ! '{"first_name":"Fat","last_name":"Mike"}'
40
+ headers:
41
+ accept:
42
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
43
+ x-riak-clientid:
44
+ - jmE3aA==
45
+ content-type:
46
+ - application/json
47
+ response: !ruby/struct:VCR::Response
48
+ status: !ruby/struct:VCR::ResponseStatus
49
+ code: 201
50
+ message: Created
51
+ headers:
52
+ x-riak-vclock:
53
+ - a85hYGBgzGDKBVIcypz/fvodtcjOYEpkzGNl+PXG4wRfFgA=
54
+ vary:
55
+ - Accept-Encoding
56
+ server:
57
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
58
+ location:
59
+ - /riak/riik_person/UVYQ98eLNZNieppMGN5BcTwKpxC
60
+ link:
61
+ - </riak/riik_person>; rel="up"
62
+ date:
63
+ - Tue, 29 Nov 2011 05:43:22 GMT
64
+ content-type:
65
+ - application/json
66
+ content-length:
67
+ - '39'
68
+ body: ! '{"first_name":"Fat","last_name":"Mike"}'
69
+ http_version: '1.1'
@@ -0,0 +1,28 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :delete
5
+ uri: http://127.0.0.1:8098/riak/riik_person/UVYQ98eLNZNieppMGN5BcTwKpxC
6
+ body:
7
+ headers:
8
+ accept:
9
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
10
+ x-riak-clientid:
11
+ - jmE3aA==
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 204
15
+ message: No Content
16
+ headers:
17
+ vary:
18
+ - Accept-Encoding
19
+ server:
20
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
21
+ date:
22
+ - Tue, 29 Nov 2011 05:43:22 GMT
23
+ content-type:
24
+ - application/json
25
+ content-length:
26
+ - '0'
27
+ body:
28
+ http_version: '1.1'
@@ -0,0 +1,63 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: http://127.0.0.1:8098/riak/riik_person/UVYQ98eLNZNieppMGN5BcTwKpxC
6
+ body:
7
+ headers:
8
+ accept:
9
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
10
+ x-riak-clientid:
11
+ - jmE3aA==
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ x-riak-vclock:
18
+ - a85hYGBgzGDKBVIcypz/fvodtcjOYEpkzGNl+PXG4wRfFgA=
19
+ vary:
20
+ - Accept-Encoding
21
+ server:
22
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
23
+ link:
24
+ - </riak/riik_person>; rel="up"
25
+ last-modified:
26
+ - Sun, 27 Nov 2011 18:48:09 GMT
27
+ etag:
28
+ - ! '"3mkiscq9OZrqDd9HOz6l21"'
29
+ date:
30
+ - Tue, 29 Nov 2011 05:43:22 GMT
31
+ content-type:
32
+ - application/json
33
+ content-length:
34
+ - '39'
35
+ body: ! '{"first_name":"Fat","last_name":"Mike"}'
36
+ http_version: '1.1'
37
+ - !ruby/struct:VCR::HTTPInteraction
38
+ request: !ruby/struct:VCR::Request
39
+ method: :get
40
+ uri: http://127.0.0.1:8098/riak/riik_person/invalid
41
+ body:
42
+ headers:
43
+ accept:
44
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
45
+ x-riak-clientid:
46
+ - jmE3aA==
47
+ response: !ruby/struct:VCR::Response
48
+ status: !ruby/struct:VCR::ResponseStatus
49
+ code: 404
50
+ message: Object Not Found
51
+ headers:
52
+ server:
53
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
54
+ date:
55
+ - Tue, 29 Nov 2011 05:43:22 GMT
56
+ content-type:
57
+ - text/plain
58
+ content-length:
59
+ - '10'
60
+ body: ! 'not found
61
+
62
+ '
63
+ http_version: '1.1'
@@ -0,0 +1,38 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :put
5
+ uri: http://127.0.0.1:8098/riak/riik_person/UVYQ98eLNZNieppMGN5BcTwKpxC?returnbody=true
6
+ body: ! '{"first_name":"Eric","last_name":"Melvin"}'
7
+ headers:
8
+ accept:
9
+ - multipart/mixed, application/json;q=0.7, */*;q=0.5
10
+ x-riak-clientid:
11
+ - jmE3aA==
12
+ content-type:
13
+ - application/json
14
+ x-riak-vclock:
15
+ - a85hYGBgzGDKBVIcypz/fvodtcjOYEpkzGNl+PXG4wRfFgA=
16
+ link:
17
+ - ''
18
+ response: !ruby/struct:VCR::Response
19
+ status: !ruby/struct:VCR::ResponseStatus
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ x-riak-vclock:
24
+ - a85hYGBgzGDKBVIcypz/fvodtcjOYEpkymNl+PXG4wRfFgA=
25
+ vary:
26
+ - Accept-Encoding
27
+ server:
28
+ - MochiWeb/1.1 WebMachine/1.9.0 (participate in the frantic)
29
+ link:
30
+ - </riak/riik_person>; rel="up"
31
+ date:
32
+ - Tue, 29 Nov 2011 05:43:22 GMT
33
+ content-type:
34
+ - application/json
35
+ content-length:
36
+ - '42'
37
+ body: ! '{"first_name":"Eric","last_name":"Melvin"}'
38
+ http_version: '1.1'
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'ripple'
3
+ require 'benchmark'
4
+
5
+ module Riik
6
+
7
+ class RiikDocument; include Riik::Document; property :number; end
8
+ class RippleDocument; include Ripple::Document; property :number, Integer; end
9
+
10
+ describe 'The performance' do
11
+ before do
12
+ WebMock.allow_net_connect!
13
+ end
14
+
15
+ after do
16
+ WebMock.disable_net_connect!
17
+ end
18
+
19
+ context 'when creating one record' do
20
+ it 'is faster than ripple' do
21
+ ripple_time = Benchmark.realtime do
22
+ RippleDocument.create(:number => 1)
23
+ end
24
+ riik_time = Benchmark.realtime do
25
+ RiikDocument.create(:number => 1)
26
+ end
27
+ riik_time.should < ripple_time
28
+ end
29
+ end
30
+
31
+ context 'when creating 300 records' do
32
+ it 'is faster than ripple' do
33
+ ripple_time = Benchmark.realtime do
34
+ 300.times.each do |i|
35
+ RippleDocument.create(:number => i)
36
+ end
37
+ end
38
+ riik_time = Benchmark.realtime do
39
+ 300.times.each do |i|
40
+ RiikDocument.create(:number => i)
41
+ end
42
+ end
43
+ riik_time.should < ripple_time
44
+ end
45
+ end
46
+
47
+ context 'when creating 1000 records' do
48
+ it 'is faster than ripple' do
49
+ ripple_time = Benchmark.realtime do
50
+ 1000.times.each do |i|
51
+ RippleDocument.create(:number => i)
52
+ end
53
+ end
54
+ riik_time = Benchmark.realtime do
55
+ 1000.times.each do |i|
56
+ RiikDocument.create(:number => i)
57
+ end
58
+ end
59
+ riik_time.should < ripple_time
60
+ end
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ module Riik
4
+ module Document
5
+ describe Finders do
6
+ context 'when finding a valid key' do
7
+ subject { person }
8
+
9
+ let(:preexisting_record) do
10
+ VCR.use_cassette('creation_of_nonexistent_key') do
11
+ Person.create(attributes)
12
+ end
13
+ end
14
+
15
+ let(:attributes) do
16
+ { :first_name => 'Fat', :last_name => 'Mike' }
17
+ end
18
+
19
+ it 'can be found' do
20
+ VCR.use_cassette('loading_of_valid_key') do
21
+ Person.find(preexisting_record.key).should be_an_instance_of(Person)
22
+ end
23
+ end
24
+
25
+ context 'when found' do
26
+ let(:person) do
27
+ VCR.use_cassette('loading_of_valid_key') do
28
+ Person.find(preexisting_record.key)
29
+ end
30
+ end
31
+
32
+ it 'sets the riak client object' do
33
+ subject.robject.should be_an_instance_of(Riak::RObject)
34
+ end
35
+
36
+ it 'set the model attributes' do
37
+ attributes.each do |key, value|
38
+ subject.send(key).should == value
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when not found' do
44
+ let(:person) do
45
+ VCR.use_cassette('loading_of_valid_key') do
46
+ Person.find('invalid')
47
+ end
48
+ end
49
+
50
+ it 'returns nil if it can not be found' do
51
+ expect { subject.should be_nil }.to raise_error
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ module Riik
4
+ module Document
5
+ describe Persistence do
6
+ subject { person }
7
+
8
+ context 'when creating' do
9
+ let(:person) { Person }
10
+
11
+ let(:attributes) do
12
+ { :first_name => 'Fat', :last_name => 'Mike' }
13
+ end
14
+
15
+ it 'can be created' do
16
+ VCR.use_cassette('creation_of_nonexistent_key') do
17
+ subject.create(attributes).should be_an_instance_of(Person)
18
+ end
19
+ end
20
+
21
+ context 'once created' do
22
+ let(:person) do
23
+ VCR.use_cassette('creation_of_nonexistent_key') do
24
+ Person.create(attributes)
25
+ end
26
+ end
27
+
28
+ it 'should exist in riak correctly' do
29
+ VCR.use_cassette('loading_of_valid_key') do
30
+ subject.bucket.get(subject.key).should be_an_instance_of(Riak::RObject)
31
+
32
+ attributes.each do |key, value|
33
+ subject.send(key).should == value
34
+ end
35
+ end
36
+ end
37
+
38
+ it 'can be updated' do
39
+ VCR.use_cassette('updating_of_valid_key') do
40
+ subject.first_name = 'Eric'
41
+ subject.last_name = 'Melvin'
42
+ subject.save
43
+ end
44
+ end
45
+
46
+ it 'can be destroyed' do
47
+ VCR.use_cassette('deletion_of_valid_key') do
48
+ subject.destroy
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ module Riik
4
+ describe Document do
5
+ subject { person }
6
+
7
+ let(:person) { Person }
8
+
9
+ it 'contains a bucket name derived from the name' do
10
+ subject.bucket_name.should == "riik_person"
11
+ end
12
+
13
+ it 'contains a bucket' do
14
+ subject.bucket.should be_an_instance_of(Riak::Bucket)
15
+ end
16
+
17
+ context 'an empty document' do
18
+ let(:person) { Person.new }
19
+
20
+ it 'knows its properties' do
21
+ [:first_name, :last_name].each do |attr|
22
+ subject.class.riik_attributes.should include(attr)
23
+ end
24
+ end
25
+
26
+ it 'responds to properties' do
27
+ [:first_name, :last_name].each do |attr|
28
+ subject.should respond_to(attr)
29
+ end
30
+ end
31
+
32
+ it 'contains a robject of content type json' do
33
+ subject.robject.should be_an_instance_of(Riak::RObject)
34
+ subject.robject.content_type.should == "application/json"
35
+ end
36
+ end
37
+
38
+ context 'with some attributes' do
39
+ let(:person) { Person.new(attributes) }
40
+
41
+ let(:attributes) do
42
+ { :first_name => 'Fat', :last_name => 'Mike' }
43
+ end
44
+
45
+ it 'assigns properties through an attributes hash' do
46
+ attributes.each do |key, value|
47
+ subject.send(key).should == value
48
+ end
49
+ end
50
+
51
+ it 'has a valid attributes hash' do
52
+ attributes.should == subject.attributes
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ module Riik
4
+ describe self do
5
+ subject { Riik }
6
+
7
+ let(:client) { Riak::Client.new }
8
+
9
+ it 'has a client' do
10
+ subject.client.should be_a_kind_of(Riak::Client)
11
+ end
12
+
13
+ it 'has a client that can be set' do
14
+ subject.client = client
15
+ subject.client.should == client
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ PROJECT_ROOT = File.expand_path("../..", __FILE__)
4
+ $LOAD_PATH << File.join(PROJECT_ROOT, "lib")
5
+
6
+ Bundler.require
7
+
8
+ require 'riik'
9
+
10
+ require 'vcr'
11
+
12
+ VCR.config do |c|
13
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
14
+ c.stub_with :webmock
15
+ c.default_cassette_options = { :record => :new_episodes }
16
+ end
17
+
18
+ # Test class.
19
+ #
20
+ module Riik
21
+ class Person
22
+ include Riik::Document
23
+
24
+ property :first_name
25
+ property :last_name
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,233 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: riik
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christopher Meiklejohn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: riak-client
16
+ requirement: &11983080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *11983080
25
+ - !ruby/object:Gem::Dependency
26
+ name: excon
27
+ requirement: &11982220 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *11982220
36
+ - !ruby/object:Gem::Dependency
37
+ name: yard
38
+ requirement: &11981240 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *11981240
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &11980600 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *11980600
58
+ - !ruby/object:Gem::Dependency
59
+ name: redcarpet
60
+ requirement: &11980100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *11980100
69
+ - !ruby/object:Gem::Dependency
70
+ name: vcr
71
+ requirement: &11979540 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *11979540
80
+ - !ruby/object:Gem::Dependency
81
+ name: webmock
82
+ requirement: &11979020 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *11979020
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec
93
+ requirement: &11978500 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *11978500
102
+ - !ruby/object:Gem::Dependency
103
+ name: rake
104
+ requirement: &11977820 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 0.9.2
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *11977820
113
+ - !ruby/object:Gem::Dependency
114
+ name: ripple
115
+ requirement: &11977240 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *11977240
124
+ - !ruby/object:Gem::Dependency
125
+ name: guard
126
+ requirement: &12025440 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *12025440
135
+ - !ruby/object:Gem::Dependency
136
+ name: guard-rspec
137
+ requirement: &12024880 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *12024880
146
+ - !ruby/object:Gem::Dependency
147
+ name: guard-yard
148
+ requirement: &12024380 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *12024380
157
+ - !ruby/object:Gem::Dependency
158
+ name: guard-ctags-bundler
159
+ requirement: &12023860 !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: *12023860
168
+ description: Lightweight object mapper for Riak.
169
+ email:
170
+ - cmeiklejohn@criticalpair.com
171
+ executables: []
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - .gitignore
176
+ - .rbenv-version
177
+ - .rspec
178
+ - .travis.yml
179
+ - .yardopts
180
+ - Gemfile
181
+ - Guardfile
182
+ - LICENSE
183
+ - README.markdown
184
+ - Rakefile
185
+ - config/tddium.yml
186
+ - lib/riik.rb
187
+ - lib/riik/document.rb
188
+ - lib/riik/document/finders.rb
189
+ - lib/riik/document/persistence.rb
190
+ - lib/riik/version.rb
191
+ - riik.gemspec
192
+ - spec/fixtures/vcr_cassettes/creation_of_nonexistent_key.yml
193
+ - spec/fixtures/vcr_cassettes/deletion_of_valid_key.yml
194
+ - spec/fixtures/vcr_cassettes/loading_of_valid_key.yml
195
+ - spec/fixtures/vcr_cassettes/updating_of_valid_key.yml
196
+ - spec/lib/performance_spec.rb
197
+ - spec/lib/riik/document/finders_spec.rb
198
+ - spec/lib/riik/document/persistence_spec.rb
199
+ - spec/lib/riik/document_spec.rb
200
+ - spec/lib/riik_spec.rb
201
+ - spec/spec_helper.rb
202
+ homepage: http://critialpair.com
203
+ licenses: []
204
+ post_install_message:
205
+ rdoc_options: []
206
+ require_paths:
207
+ - lib
208
+ required_ruby_version: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ segments:
215
+ - 0
216
+ hash: -3432467302917107998
217
+ required_rubygems_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ segments:
224
+ - 0
225
+ hash: -3432467302917107998
226
+ requirements: []
227
+ rubyforge_project:
228
+ rubygems_version: 1.8.11
229
+ signing_key:
230
+ specification_version: 3
231
+ summary: Lightweight object mapper for Riak.
232
+ test_files: []
233
+ has_rdoc: