couch_potato 0.5.1 → 0.5.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.
- data/README.md +3 -0
- data/lib/couch_potato/database.rb +22 -12
- data/lib/couch_potato/persistence/attachments.rb +1 -1
- data/lib/couch_potato/version.rb +1 -1
- data/lib/couch_potato/view/view_query.rb +5 -1
- data/lib/couch_potato.rb +2 -0
- data/spec/property_spec.rb +1 -1
- data/spec/unit/database_spec.rb +40 -0
- data/spec/unit/json_spec.rb +6 -0
- data/spec/unit/view_query_spec.rb +21 -13
- metadata +2 -34
data/README.md
CHANGED
@@ -256,6 +256,9 @@ If you have larger structures and you only want to load some attributes you can
|
|
256
256
|
|
257
257
|
CouchPotato.database.view(User.everyone).first.name # => "joe"
|
258
258
|
CouchPotato.database.view(User.everyone).first.bio # => nil
|
259
|
+
|
260
|
+
CouchPotato.database.first(User.everyone).name # => "joe" # convenience function, returns nil if nothing found
|
261
|
+
CouchPotato.database.first!(User.everyone) # would raise CouchPotato::NotFound if nothing was found
|
259
262
|
|
260
263
|
You can also pass in custom map/reduce functions with the custom view spec:
|
261
264
|
|
@@ -4,7 +4,7 @@ module CouchPotato
|
|
4
4
|
class ValidationsFailedError < ::StandardError; end
|
5
5
|
|
6
6
|
def initialize(couchrest_database)
|
7
|
-
@
|
7
|
+
@couchrest_database = couchrest_database
|
8
8
|
begin
|
9
9
|
couchrest_database.info
|
10
10
|
rescue RestClient::ResourceNotFound
|
@@ -45,7 +45,7 @@ module CouchPotato
|
|
45
45
|
# db.view(User.all(keys: [1, 2, 3]))
|
46
46
|
def view(spec)
|
47
47
|
results = CouchPotato::View::ViewQuery.new(
|
48
|
-
|
48
|
+
couchrest_database,
|
49
49
|
spec.design_document,
|
50
50
|
{spec.view_name => {
|
51
51
|
:map => spec.map_function,
|
@@ -60,6 +60,16 @@ module CouchPotato
|
|
60
60
|
end if processed_results.respond_to?(:each)
|
61
61
|
processed_results
|
62
62
|
end
|
63
|
+
|
64
|
+
# returns the first result from a #view query or nil
|
65
|
+
def first(spec)
|
66
|
+
view(spec).first
|
67
|
+
end
|
68
|
+
|
69
|
+
# returns th first result from a #view or raises CouchPotato::NotFound
|
70
|
+
def first!(spec)
|
71
|
+
first(spec) || raise(CouchPotato::NotFound)
|
72
|
+
end
|
63
73
|
|
64
74
|
# saves a document. returns true on success, false on failure
|
65
75
|
def save_document(document, validate = true)
|
@@ -81,7 +91,7 @@ module CouchPotato
|
|
81
91
|
def destroy_document(document)
|
82
92
|
document.run_callbacks :destroy do
|
83
93
|
document._deleted = true
|
84
|
-
|
94
|
+
couchrest_database.delete_doc document.to_hash
|
85
95
|
end
|
86
96
|
document._id = nil
|
87
97
|
document._rev = nil
|
@@ -92,7 +102,7 @@ module CouchPotato
|
|
92
102
|
def load_document(id)
|
93
103
|
raise "Can't load a document without an id (got nil)" if id.nil?
|
94
104
|
begin
|
95
|
-
instance =
|
105
|
+
instance = couchrest_database.get(id)
|
96
106
|
instance.database = self
|
97
107
|
instance
|
98
108
|
rescue(RestClient::ResourceNotFound)
|
@@ -102,7 +112,12 @@ module CouchPotato
|
|
102
112
|
alias_method :load, :load_document
|
103
113
|
|
104
114
|
def inspect #:nodoc:
|
105
|
-
"#<CouchPotato::Database @root=\"#{
|
115
|
+
"#<CouchPotato::Database @root=\"#{couchrest_database.root}\">"
|
116
|
+
end
|
117
|
+
|
118
|
+
# returns the underlying CouchRest::Database instance
|
119
|
+
def couchrest_database
|
120
|
+
@couchrest_database
|
106
121
|
end
|
107
122
|
|
108
123
|
private
|
@@ -121,7 +136,7 @@ module CouchPotato
|
|
121
136
|
|
122
137
|
document.run_callbacks :save do
|
123
138
|
document.run_callbacks :create do
|
124
|
-
res =
|
139
|
+
res = couchrest_database.save_doc document.to_hash
|
125
140
|
document._rev = res['rev']
|
126
141
|
document._id = res['id']
|
127
142
|
end
|
@@ -141,7 +156,7 @@ module CouchPotato
|
|
141
156
|
|
142
157
|
document.run_callbacks :save do
|
143
158
|
document.run_callbacks :update do
|
144
|
-
res =
|
159
|
+
res = couchrest_database.save_doc document.to_hash
|
145
160
|
document._rev = res['rev']
|
146
161
|
end
|
147
162
|
end
|
@@ -156,10 +171,5 @@ module CouchPotato
|
|
156
171
|
end
|
157
172
|
document.errors.empty?
|
158
173
|
end
|
159
|
-
|
160
|
-
def database
|
161
|
-
@database
|
162
|
-
end
|
163
|
-
|
164
174
|
end
|
165
175
|
end
|
data/lib/couch_potato/version.rb
CHANGED
@@ -41,7 +41,11 @@ module CouchPotato
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def view_functions
|
44
|
-
|
44
|
+
if @reduce_function
|
45
|
+
{'map' => @map_function, 'reduce' => @reduce_function}
|
46
|
+
else
|
47
|
+
{'map' => @map_function}
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
def empty_design_document
|
data/lib/couch_potato.rb
CHANGED
@@ -10,6 +10,8 @@ JSON.create_id = 'ruby_class'
|
|
10
10
|
module CouchPotato
|
11
11
|
Config = Struct.new(:database_name, :validation_framework).new
|
12
12
|
Config.validation_framework = :active_model
|
13
|
+
|
14
|
+
class NotFound < StandardError; end
|
13
15
|
|
14
16
|
# Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
|
15
17
|
def self.database
|
data/spec/property_spec.rb
CHANGED
@@ -124,7 +124,7 @@ describe 'properties' do
|
|
124
124
|
db.should_receive(:save_doc).with do |attributes|
|
125
125
|
attributes.has_key?(:ship_address).should == true
|
126
126
|
end.and_return({})
|
127
|
-
CouchPotato.database.stub(:
|
127
|
+
CouchPotato.database.stub(:couchrest_database).and_return(db)
|
128
128
|
CouchPotato.database.save_document! p
|
129
129
|
end
|
130
130
|
|
data/spec/unit/database_spec.rb
CHANGED
@@ -207,6 +207,46 @@ describe CouchPotato::Database, 'save_document' do
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
+
describe CouchPotato::Database, 'first' do
|
211
|
+
before(:each) do
|
212
|
+
@couchrest_db = stub('couchrest db').as_null_object
|
213
|
+
@db = CouchPotato::Database.new(@couchrest_db)
|
214
|
+
@result = stub('result')
|
215
|
+
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
216
|
+
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should return the first result from a view query" do
|
220
|
+
@db.first(@spec).should == @result
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should return nil if there are no results" do
|
224
|
+
@spec.stub(:process_results => [])
|
225
|
+
@db.first(@spec).should be_nil
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe CouchPotato::Database, 'first!' do
|
230
|
+
before(:each) do
|
231
|
+
@couchrest_db = stub('couchrest db').as_null_object
|
232
|
+
@db = CouchPotato::Database.new(@couchrest_db)
|
233
|
+
@result = stub('result')
|
234
|
+
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
235
|
+
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should return the first result from a view query" do
|
239
|
+
@db.first!(@spec).should == @result
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should raise an error if there are no results" do
|
243
|
+
@spec.stub(:process_results => [])
|
244
|
+
lambda {
|
245
|
+
@db.first!(@spec)
|
246
|
+
}.should raise_error(CouchPotato::NotFound)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
210
250
|
describe CouchPotato::Database, 'view' do
|
211
251
|
before(:each) do
|
212
252
|
@couchrest_db = stub('couchrest db').as_null_object
|
data/spec/unit/json_spec.rb
CHANGED
@@ -12,6 +12,12 @@ describe CouchPotato::Persistence::Json do
|
|
12
12
|
sake = Drink.new(:alcohol => "18%")
|
13
13
|
sake.to_hash[JSON.create_id].should eql("Drink")
|
14
14
|
end
|
15
|
+
|
16
|
+
it "should not include _attachments if there are none" do
|
17
|
+
sake = Drink.new(:alcohol => "18%")
|
18
|
+
sake.to_hash.keys.should_not include('_attachments')
|
19
|
+
end
|
20
|
+
|
15
21
|
end
|
16
22
|
|
17
23
|
context '.json_create' do
|
@@ -26,53 +26,61 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
26
26
|
it "should update a view when the map function has changed" do
|
27
27
|
db = mock 'db', :get => {'views' => {'view2' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}}, :view => nil
|
28
28
|
db.should_receive(:save_doc)
|
29
|
-
CouchPotato::View::ViewQuery.new(db, 'design', :view2 => {:map => '<new map_code>', :
|
29
|
+
CouchPotato::View::ViewQuery.new(db, 'design', :view2 => {:map => '<new map_code>', :reduce => '<reduce_code>'}).query_view!
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not pass in a reduce key if there is no reduce function" do
|
33
|
+
db = mock 'db', :get => {'views' => {}}, :view => nil
|
34
|
+
|
35
|
+
db.should_receive(:save_doc).with('views' => {'view3' => {'map' => '<map code>'}})
|
36
|
+
|
37
|
+
CouchPotato::View::ViewQuery.new(db, 'design', :view3 => {:map => '<map code>', :reduce => nil}).query_view!
|
30
38
|
end
|
31
39
|
|
32
40
|
it "should update a view when the reduce function has changed" do
|
33
|
-
db = mock 'db', :get => {'views' => {'
|
41
|
+
db = mock 'db', :get => {'views' => {'view4' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}}, :view => nil
|
34
42
|
db.should_receive(:save_doc)
|
35
|
-
CouchPotato::View::ViewQuery.new(db, 'design', :
|
43
|
+
CouchPotato::View::ViewQuery.new(db, 'design', :view4 => {:map => '<map_code>', :reduce => '<new reduce_code>'}).query_view!
|
36
44
|
end
|
37
45
|
|
38
46
|
it "should update a view when the list function has changed" do
|
39
47
|
db = mock 'db', :get => {
|
40
|
-
'views' => {'
|
48
|
+
'views' => {'view5' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
41
49
|
'lists' => {'list1' => '<list_code>'}
|
42
50
|
}, :view => nil
|
43
51
|
db.should_receive(:save_doc)
|
44
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:
|
52
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view5 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list1 => '<new_list_code>').query_view!
|
45
53
|
end
|
46
54
|
|
47
55
|
it "should update a view when there wasn't a list function but now there is one" do
|
48
56
|
db = mock 'db', :get => {
|
49
|
-
'views' => {'
|
57
|
+
'views' => {'view6' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}
|
50
58
|
}, :view => nil
|
51
59
|
db.should_receive(:save_doc)
|
52
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:
|
60
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view6 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list1 => '<new_list_code>').query_view!
|
53
61
|
end
|
54
62
|
|
55
63
|
it "should not update a view when there is a list function but no list function is passed" do
|
56
64
|
db = mock 'db', :get => {
|
57
|
-
'views' => {'
|
65
|
+
'views' => {'view7' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
58
66
|
'lists' => {'list1' => '<list_code>'}
|
59
67
|
}, :view => nil
|
60
68
|
db.should_not_receive(:save_doc)
|
61
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:
|
69
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view7 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, {}).query_view!
|
62
70
|
end
|
63
71
|
|
64
72
|
it "should not update a view when there were no lists before and no list function is passed" do
|
65
73
|
db = mock 'db', :get => {
|
66
|
-
'views' => {'
|
74
|
+
'views' => {'view8' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}
|
67
75
|
}, :view => nil
|
68
76
|
db.should_not_receive(:save_doc)
|
69
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:
|
77
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view8 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, {}).query_view!
|
70
78
|
end
|
71
79
|
|
72
80
|
it "should query CouchRest directly when querying a list" do
|
73
81
|
db = stub('db').as_null_object
|
74
|
-
CouchRest.should_receive(:get).with('http://127.0.0.1:5984/couch_potato_test/_design/my_design/_list/list1/
|
75
|
-
CouchPotato::View::ViewQuery.new(db, 'my_design', {:
|
82
|
+
CouchRest.should_receive(:get).with('http://127.0.0.1:5984/couch_potato_test/_design/my_design/_list/list1/view9?key=1')
|
83
|
+
CouchPotato::View::ViewQuery.new(db, 'my_design', {:view9 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list1 => '<new_list_code>').query_view!(:key => 1)
|
76
84
|
end
|
77
85
|
|
78
86
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_potato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 9
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 0
|
8
|
-
- 5
|
9
|
-
- 1
|
10
|
-
version: 0.5.1
|
5
|
+
version: 0.5.2
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Alexander Lang
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-18 00:00:00 +02:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
@@ -26,9 +21,6 @@ dependencies:
|
|
26
21
|
requirements:
|
27
22
|
- - ">="
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 0
|
32
24
|
version: "0"
|
33
25
|
type: :runtime
|
34
26
|
version_requirements: *id001
|
@@ -40,11 +32,6 @@ dependencies:
|
|
40
32
|
requirements:
|
41
33
|
- - ">="
|
42
34
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 21
|
44
|
-
segments:
|
45
|
-
- 1
|
46
|
-
- 0
|
47
|
-
- 1
|
48
35
|
version: 1.0.1
|
49
36
|
type: :runtime
|
50
37
|
version_requirements: *id002
|
@@ -56,9 +43,6 @@ dependencies:
|
|
56
43
|
requirements:
|
57
44
|
- - ">="
|
58
45
|
- !ruby/object:Gem::Version
|
59
|
-
hash: 3
|
60
|
-
segments:
|
61
|
-
- 0
|
62
46
|
version: "0"
|
63
47
|
type: :runtime
|
64
48
|
version_requirements: *id003
|
@@ -70,10 +54,6 @@ dependencies:
|
|
70
54
|
requirements:
|
71
55
|
- - ">="
|
72
56
|
- !ruby/object:Gem::Version
|
73
|
-
hash: 3
|
74
|
-
segments:
|
75
|
-
- 2
|
76
|
-
- 0
|
77
57
|
version: "2.0"
|
78
58
|
type: :development
|
79
59
|
version_requirements: *id004
|
@@ -85,9 +65,6 @@ dependencies:
|
|
85
65
|
requirements:
|
86
66
|
- - ">="
|
87
67
|
- !ruby/object:Gem::Version
|
88
|
-
hash: 3
|
89
|
-
segments:
|
90
|
-
- 0
|
91
68
|
version: "0"
|
92
69
|
type: :development
|
93
70
|
version_requirements: *id005
|
@@ -99,9 +76,6 @@ dependencies:
|
|
99
76
|
requirements:
|
100
77
|
- - ">="
|
101
78
|
- !ruby/object:Gem::Version
|
102
|
-
hash: 3
|
103
|
-
segments:
|
104
|
-
- 0
|
105
79
|
version: "0"
|
106
80
|
type: :development
|
107
81
|
version_requirements: *id006
|
@@ -215,18 +189,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
189
|
requirements:
|
216
190
|
- - ">="
|
217
191
|
- !ruby/object:Gem::Version
|
218
|
-
hash: 3
|
219
|
-
segments:
|
220
|
-
- 0
|
221
192
|
version: "0"
|
222
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
194
|
none: false
|
224
195
|
requirements:
|
225
196
|
- - ">="
|
226
197
|
- !ruby/object:Gem::Version
|
227
|
-
hash: 3
|
228
|
-
segments:
|
229
|
-
- 0
|
230
198
|
version: "0"
|
231
199
|
requirements: []
|
232
200
|
|