ork 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +51 -1
- data/lib/ork/errors.rb +2 -0
- data/lib/ork/model/class_methods.rb +7 -0
- data/lib/ork/{embedded.rb → model/embedded.rb} +1 -1
- data/lib/ork/model/finders.rb +13 -12
- data/lib/ork/result_set.rb +79 -0
- data/lib/ork.rb +2 -1
- data/ork.gemspec +2 -2
- data/test/result_set_test.rb +171 -0
- metadata +8 -6
- data/lib/ork/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 057b1b4f7eb4e0328a9998738e477947bacdacc3
|
4
|
+
data.tar.gz: d6522930cdaf1e25e16b19988be2901db7968e9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbbc733bd2cc6dc9954827ed1d170fe2a27f95847e114bbaa000666a823be271e6a9ef018da6afb7d2e8c3f093364ad039d3f81ede44d3755adde4b1ab58adb2
|
7
|
+
data.tar.gz: e4ac8f95ace5511046f100a33f7005a56eb17cdeb3589d2d11174848067dfd23d697ae36671c13f3d0545f7f929ca90df99864c4c9671cfc45b2c0eed96e10ae
|
data/README.md
CHANGED
@@ -172,11 +172,61 @@ Provides an accessor to the object that `embeds` the current model.
|
|
172
172
|
embedded :post, :Post
|
173
173
|
```
|
174
174
|
|
175
|
+
## Pagination
|
176
|
+
|
177
|
+
Pagination is a key feature introduced in _Riak 1.4_ and it is supported as well!
|
178
|
+
|
179
|
+
`Ork` will return the _enumerable_ `Ork::ResultSet` object which stores the keys and also the resulting objects.
|
180
|
+
The __keys__ are immediately loaded, but the __objects__ will be lazy loaded.
|
181
|
+
|
182
|
+
Given it uses the same API than `riak_client` let's jump into the examples.
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
|
186
|
+
resultset = Post.find(:age, 19, max_results: 3)
|
187
|
+
# => #<Ork::ResultSet:{:max_results=>3} ['object_key_1', 'object_key_2', 'object_key_3']>
|
188
|
+
|
189
|
+
resultset.keys
|
190
|
+
# => ['object_key_1', 'object_key_2', 'object_key_3']
|
191
|
+
|
192
|
+
resultset.all
|
193
|
+
# => [#<Post:1 ...>, #<Post:2 ...>, #<Post:3 ...>]
|
194
|
+
|
195
|
+
##
|
196
|
+
# Advance to next page
|
197
|
+
##
|
198
|
+
|
199
|
+
resultset.has_next_page?
|
200
|
+
# => true
|
201
|
+
|
202
|
+
next_resultset = resultset.next_page
|
203
|
+
# => #<Ork::ResultSet:{:max_results=>3, :continuation=>'a_continuation_string'}
|
204
|
+
# ['object_key_4', 'object_key_5']>
|
205
|
+
|
206
|
+
next_resultset.has_next_page?
|
207
|
+
# => false
|
208
|
+
|
209
|
+
next_resultset.next_page
|
210
|
+
# => raises Ork::NoNextPage: There is no next page
|
211
|
+
|
212
|
+
##
|
213
|
+
# Skip pages and start from a continuation
|
214
|
+
##
|
215
|
+
|
216
|
+
resultset2 = Post.find(:age, 19, max_results: 3, continuation: 'a_continuation_string')
|
217
|
+
# => #<Ork::ResultSet:{:max_results=>3, :continuation=>'a_continuation_string'}
|
218
|
+
# ['object_key_4', 'object_key_5']>
|
219
|
+
|
220
|
+
resultset2 == resultset.next_page
|
221
|
+
# => true
|
222
|
+
|
223
|
+
```
|
224
|
+
|
175
225
|
## Validations
|
176
226
|
|
177
227
|
As you can see, there is no reference to validations in this document and I'm aware of that!
|
178
228
|
The validation logic for _nested embedded objects_ makes the code more complex than I want.
|
179
|
-
Given that I want to keep this gem as simple as I can, I decided to avoid _object validation_ logic here and promote the use of other gems.
|
229
|
+
Given that I want to keep this gem as simple as I can, I decided to avoid _object validation_ logic here and promote the use of other gems.
|
180
230
|
|
181
231
|
There are good implementations for object validation like [hatch](https://github.com/tonchis/hatch) or [scrivener](https://github.com/soveran/scrivener) which they do a great job!
|
182
232
|
If you don't know them, you should take a look, but remember that you are free to use your prefered _gem_ or even your own method!
|
data/lib/ork/errors.rb
CHANGED
@@ -42,6 +42,13 @@ module Ork::Model
|
|
42
42
|
# When the parameter is nil, it will return the content_type.
|
43
43
|
# It also sets as default the standard content_type.
|
44
44
|
#
|
45
|
+
# Example:
|
46
|
+
# class User
|
47
|
+
# include Ork:Document
|
48
|
+
#
|
49
|
+
# content_type 'text/plain'
|
50
|
+
# end
|
51
|
+
#
|
45
52
|
def content_type(type = nil)
|
46
53
|
@content_type = type unless type.nil?
|
47
54
|
@content_type ||= 'application/json'
|
data/lib/ork/model/finders.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../result_set'
|
2
|
+
|
1
3
|
module Ork::Model
|
2
4
|
module Finders
|
3
5
|
|
@@ -20,17 +22,22 @@ module Ork::Model
|
|
20
22
|
alias :exists? :exist?
|
21
23
|
|
22
24
|
# Find all documents in the Document's bucket and return them.
|
23
|
-
# @return
|
25
|
+
# @return Ork::ResultSet<Document> all found documents in the bucket
|
24
26
|
#
|
25
27
|
# @Note: This operation is incredibly expensive and should not
|
26
28
|
# be used in production applications.
|
27
29
|
#
|
28
30
|
def all
|
29
|
-
|
31
|
+
Ork::ResultSet.all(self)
|
30
32
|
end
|
31
33
|
alias :list :all
|
32
34
|
|
33
35
|
# Find values in indexed fields.
|
36
|
+
# @return Ork::ResultSet<Document> found documents in the bucket
|
37
|
+
#
|
38
|
+
# options - Hash configs for pagination.
|
39
|
+
# :max_results - Number
|
40
|
+
# :continuation - String
|
34
41
|
#
|
35
42
|
# Example:
|
36
43
|
#
|
@@ -42,20 +49,20 @@ module Ork::Model
|
|
42
49
|
# end
|
43
50
|
#
|
44
51
|
# u = User.create(name: 'John')
|
45
|
-
# User.find(name
|
52
|
+
# User.find(:name, 'John', max_results: 5).include?(u)
|
46
53
|
# # => true
|
47
54
|
#
|
48
|
-
# User.find(name
|
55
|
+
# User.find(:name, 'Mike').include?(u)
|
49
56
|
# # => false
|
50
57
|
#
|
51
58
|
# Note: If the key was not defined, an
|
52
59
|
# `Ork::IndexNotFound` exception is raised.
|
53
60
|
#
|
54
|
-
def find(by_index, value)
|
61
|
+
def find(by_index, value, options = {})
|
55
62
|
raise Ork::IndexNotFound unless indices.has_key? by_index
|
56
63
|
|
57
64
|
index = indices[by_index]
|
58
|
-
|
65
|
+
Ork::ResultSet.new(self, index, value, options)
|
59
66
|
end
|
60
67
|
|
61
68
|
private
|
@@ -66,11 +73,5 @@ module Ork::Model
|
|
66
73
|
raise e unless e.not_found?
|
67
74
|
end
|
68
75
|
|
69
|
-
def load_robjects(robjects)
|
70
|
-
robjects.map do |id, robject|
|
71
|
-
new.send(:__load_robject!, id, robject)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
76
|
end
|
76
77
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Ork
|
4
|
+
class ResultSet
|
5
|
+
extend Forwardable
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def_delegators :keys, :size, :count, :length, :empty?
|
9
|
+
def_delegators :all, :each, :first, :last
|
10
|
+
|
11
|
+
def initialize(model, index, query, options={})
|
12
|
+
@model, @index, @query, @options = model, index, query, options
|
13
|
+
@bucket = @model.bucket
|
14
|
+
end
|
15
|
+
|
16
|
+
# Find all documents in the Document's bucket and return them.
|
17
|
+
# @return Ork::ResultSet<Document> all the documents in the bucket
|
18
|
+
#
|
19
|
+
# @Note: This operation is incredibly expensive and should not
|
20
|
+
# be used in production applications.
|
21
|
+
#
|
22
|
+
def self.all(model)
|
23
|
+
new(model, nil, nil).tap do |r|
|
24
|
+
r.instance_variable_set(:@keys, model.bucket.keys)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Pretty print for the ResultSet
|
29
|
+
# It uses keys when the objects are not present.
|
30
|
+
#
|
31
|
+
def inspect
|
32
|
+
string = "#<#{self.class}:#{@options} %s>"
|
33
|
+
|
34
|
+
string % (@all || self.keys).inspect
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the array of matched keys
|
38
|
+
#
|
39
|
+
def keys(&block)
|
40
|
+
@keys ||=
|
41
|
+
@bucket.client.backend do |b|
|
42
|
+
b.get_index @bucket, @index.riak_name, @query, @options, &block
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get the array of objects
|
47
|
+
#
|
48
|
+
def all
|
49
|
+
return if self.keys.nil?
|
50
|
+
@all ||= load_robjects @bucket.get_many(@keys)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get a new ResultSet fetch for the next page
|
54
|
+
#
|
55
|
+
def next_page
|
56
|
+
raise Ork::NoNextPage.new 'There is no next page' unless has_next_page?
|
57
|
+
|
58
|
+
self.class.new(@model,
|
59
|
+
@index,
|
60
|
+
@query,
|
61
|
+
@options.merge(continuation: keys.continuation))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Determine whether a SecondaryIndex fetch has a next page available
|
65
|
+
#
|
66
|
+
def has_next_page?
|
67
|
+
keys.respond_to?(:continuation) && !!keys.continuation
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def load_robjects(robjects)
|
73
|
+
robjects.map do |id, robject|
|
74
|
+
@model.new.send(:__load_robject!, id, robject)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
data/lib/ork.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'ork/connection'
|
2
2
|
require 'ork/model'
|
3
3
|
require 'ork/model/document'
|
4
|
-
require 'ork/embedded'
|
4
|
+
require 'ork/model/embedded'
|
5
5
|
require 'ork/utils'
|
6
6
|
require 'ork/errors'
|
7
7
|
require "riak"
|
8
8
|
|
9
9
|
module Ork
|
10
|
+
VERSION = "0.1.2"
|
10
11
|
|
11
12
|
def self.conn
|
12
13
|
@conn ||= Ork::Connection.new
|
data/ork.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'ork'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.2'
|
4
4
|
s.date = Time.now.strftime('%Y-%m-%d')
|
5
5
|
s.summary = 'Ruby modeling layer for Riak.'
|
6
6
|
s.description = 'Ork is a small Ruby modeling layer for Riak, inspired by Ohm.'
|
@@ -19,6 +19,6 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.add_dependency 'riak-client'
|
21
21
|
s.add_development_dependency 'protest'
|
22
|
-
s.add_development_dependency '
|
22
|
+
s.add_development_dependency 'mocha'
|
23
23
|
end
|
24
24
|
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
Protest.describe 'ResultSet' do
|
4
|
+
class Post
|
5
|
+
include Ork::Document
|
6
|
+
attribute :name
|
7
|
+
|
8
|
+
index :name
|
9
|
+
end
|
10
|
+
|
11
|
+
setup do
|
12
|
+
randomize_bucket_name Post
|
13
|
+
@post1 = Post.create name: 'Post 1'
|
14
|
+
@post2 = Post.create name: 'Post 2'
|
15
|
+
end
|
16
|
+
|
17
|
+
context '*all*' do
|
18
|
+
setup do
|
19
|
+
@all = Ork::ResultSet.all(Post)
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'index and query are nil' do
|
23
|
+
assert_equal nil, @all.instance_variable_get(:@index)
|
24
|
+
assert_equal nil, @all.instance_variable_get(:@query)
|
25
|
+
end
|
26
|
+
|
27
|
+
test 'model, bucket are not nil' do
|
28
|
+
assert_equal Post, @all.instance_variable_get(:@model)
|
29
|
+
assert_equal Post.bucket, @all.instance_variable_get(:@bucket)
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'it has the keys set but not the loaded objects' do
|
33
|
+
key1, key2 = Post.bucket.keys
|
34
|
+
assert @all.instance_variable_get(:@keys).include? key1
|
35
|
+
assert @all.instance_variable_get(:@keys).include? key2
|
36
|
+
assert_equal nil, @all.instance_variable_get(:@all)
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'it is not paginated' do
|
40
|
+
deny @all.has_next_page?
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'it returns all the objects' do
|
44
|
+
assert_equal 2, @all.size
|
45
|
+
assert @all.include? @post1
|
46
|
+
assert @all.include? @post2
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'it raises an exception when call next_page if does not have next page' do
|
51
|
+
resultset = Ork::ResultSet.all(Post)
|
52
|
+
|
53
|
+
deny resultset.has_next_page?
|
54
|
+
assert_raise Ork::NoNextPage do
|
55
|
+
resultset.next_page
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '*new*' do
|
60
|
+
setup do
|
61
|
+
@post3 = Post.create name: 'Post 1'
|
62
|
+
|
63
|
+
@index = Post.indices[:name]
|
64
|
+
@resultset = Ork::ResultSet.new(Post, @index, 'Post 1')
|
65
|
+
end
|
66
|
+
|
67
|
+
test 'the keys are not loaded' do
|
68
|
+
assert_equal nil, @resultset.instance_variable_get(:@keys)
|
69
|
+
assert_equal nil, @resultset.instance_variable_get(:@all)
|
70
|
+
end
|
71
|
+
|
72
|
+
test ':size, :count :length will not load the robjects' do
|
73
|
+
assert_equal 2, @resultset.size
|
74
|
+
assert_equal 2, @resultset.length
|
75
|
+
assert_equal 2, @resultset.count
|
76
|
+
|
77
|
+
assert @resultset.instance_variable_get(:@keys).include? @post1.id
|
78
|
+
assert @resultset.instance_variable_get(:@keys).include? @post3.id
|
79
|
+
assert_equal nil, @resultset.instance_variable_get(:@all)
|
80
|
+
end
|
81
|
+
|
82
|
+
test 'can be iterable and iterates over the objects' do
|
83
|
+
assert @resultset.respond_to?(:each)
|
84
|
+
|
85
|
+
@resultset.each{|post| assert_equal Post, post.class}
|
86
|
+
end
|
87
|
+
|
88
|
+
test 'it acts like an array' do
|
89
|
+
deny @resultset.empty?
|
90
|
+
assert_equal Post, @resultset.first.class
|
91
|
+
assert_equal Post, @resultset.last.class
|
92
|
+
assert @resultset.include? @post1
|
93
|
+
assert @resultset.include? @post3
|
94
|
+
end
|
95
|
+
|
96
|
+
test 'it shows the options and keys when objects are not loaded' do
|
97
|
+
@resultset = Ork::ResultSet.new(Post, @index, 'Post 2', max_results: 5)
|
98
|
+
expected = "#<Ork::ResultSet:{:max_results=>5} [\"#{@post2.id}\"]>"
|
99
|
+
|
100
|
+
assert_equal expected, @resultset.inspect
|
101
|
+
end
|
102
|
+
|
103
|
+
test 'it shows the options and objects when are loaded' do
|
104
|
+
@resultset = Ork::ResultSet.new(Post, @index, 'Post 2', max_results: 5)
|
105
|
+
expected = "#<Ork::ResultSet:{:max_results=>5} [#{@post2.inspect}]>"
|
106
|
+
@resultset.all
|
107
|
+
|
108
|
+
assert_equal expected, @resultset.inspect
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "*options*" do
|
113
|
+
setup do
|
114
|
+
@post3 = Post.create name: 'Post 1'
|
115
|
+
@index = Post.indices[:name]
|
116
|
+
end
|
117
|
+
|
118
|
+
context ':max_results' do
|
119
|
+
test 'it behaves like nil when its invalid' do
|
120
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 1', max_results: -5)
|
121
|
+
|
122
|
+
assert_equal nil, resultset.keys
|
123
|
+
assert_equal nil, resultset.all
|
124
|
+
end
|
125
|
+
|
126
|
+
test 'it returns an empty array when did not find any object' do
|
127
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 9', max_results: 5)
|
128
|
+
|
129
|
+
assert_equal [], resultset.keys
|
130
|
+
assert_equal [], resultset.all
|
131
|
+
end
|
132
|
+
|
133
|
+
test 'return no more than specified objects' do
|
134
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 1', max_results: 1)
|
135
|
+
|
136
|
+
assert_equal 3, Post.all.size
|
137
|
+
assert_equal 1, resultset.size
|
138
|
+
assert resultset.has_next_page?
|
139
|
+
end
|
140
|
+
|
141
|
+
test 'fetch the next page and return a new resultset' do
|
142
|
+
post4 = Post.create name: 'Post 1'
|
143
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 1', max_results: 2)
|
144
|
+
next_page = resultset.next_page
|
145
|
+
|
146
|
+
assert_equal 2, resultset.size
|
147
|
+
assert_equal 1, next_page.size
|
148
|
+
deny next_page.has_next_page?
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context ':continuation' do
|
153
|
+
test 'it behaves like nil when its invalid' do
|
154
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 1', continuation: 'not_a_continuation')
|
155
|
+
|
156
|
+
assert_equal nil, resultset.keys
|
157
|
+
assert_equal nil, resultset.all
|
158
|
+
end
|
159
|
+
|
160
|
+
test 'get a specific page' do
|
161
|
+
post4 = Post.create name: 'Post 1'
|
162
|
+
resultset = Ork::ResultSet.new(Post, @index, 'Post 1', max_results: 2)
|
163
|
+
continuation = resultset.keys.continuation
|
164
|
+
|
165
|
+
last_page = Ork::ResultSet.new(Post, @index, 'Post 1', continuation: continuation)
|
166
|
+
|
167
|
+
assert_equal resultset.next_page.keys, last_page.keys
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emiliano Mancuso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: riak-client
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: mocha
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '>='
|
@@ -62,19 +62,20 @@ files:
|
|
62
62
|
- README.md
|
63
63
|
- rakefile
|
64
64
|
- lib/ork/connection.rb
|
65
|
-
- lib/ork/embedded.rb
|
66
65
|
- lib/ork/errors.rb
|
67
66
|
- lib/ork/model/associations.rb
|
68
67
|
- lib/ork/model/class_methods.rb
|
69
68
|
- lib/ork/model/document.rb
|
69
|
+
- lib/ork/model/embedded.rb
|
70
70
|
- lib/ork/model/finders.rb
|
71
71
|
- lib/ork/model/index.rb
|
72
72
|
- lib/ork/model.rb
|
73
|
+
- lib/ork/result_set.rb
|
73
74
|
- lib/ork/utils.rb
|
74
|
-
- lib/ork/version.rb
|
75
75
|
- lib/ork.rb
|
76
76
|
- ork.gemspec
|
77
77
|
- test/helper.rb
|
78
|
+
- test/result_set_test.rb
|
78
79
|
homepage: http://github.com/emancu/ork
|
79
80
|
licenses:
|
80
81
|
- MIT
|
@@ -95,9 +96,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
96
|
version: '0'
|
96
97
|
requirements: []
|
97
98
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.1.
|
99
|
+
rubygems_version: 2.1.11
|
99
100
|
signing_key:
|
100
101
|
specification_version: 4
|
101
102
|
summary: Ruby modeling layer for Riak.
|
102
103
|
test_files:
|
103
104
|
- test/helper.rb
|
105
|
+
- test/result_set_test.rb
|
data/lib/ork/version.rb
DELETED