public
Fork of chuyeow/activecouch
Description: ActiveCouch is a simple, convenient, Ruby-idiomatic wrapper for CouchDB
Homepage: http://github.com/arunthampi/activecouch
Clone URL: git://github.com/arunthampi/activecouch.git
- Fully functional :offset and :limit methods for ActiveCouch::Base#find
- ActiveCouch::Base#count method now uses the official CouchDB API, and is 
therefore much faster
arunthampi (author)
Thu Jun 12 03:31:24 -0700 2008
commit  9c62ac1f27befa7c511b6cfe42a8f44e5881f5ba
tree    88b986f2ce886a9ed8ea5eb25767e181fcb059ea
parent  24c72c59b540985260b43e969e1dc6bdd5ff8aa2
...
1
2
 
3
...
 
1
2
3
0
@@ -1 +1 @@
0
-0.1.2
0
\ No newline at end of file
0
+0.1.9
0
\ No newline at end of file
...
347
348
349
350
351
352
353
354
355
356
 
357
358
359
...
369
370
371
372
373
374
 
 
 
 
 
375
376
377
...
483
484
485
486
487
 
 
488
489
490
 
 
 
491
492
493
...
507
508
509
510
511
512
 
 
 
 
 
513
514
515
516
 
 
 
517
518
519
520
521
 
522
523
524
...
347
348
349
 
 
 
 
350
351
 
352
353
354
355
...
365
366
367
 
 
 
368
369
370
371
372
373
374
375
...
481
482
483
 
 
484
485
486
487
488
489
490
491
492
493
494
...
508
509
510
 
 
 
511
512
513
514
515
516
 
 
 
517
518
519
520
 
 
 
 
521
522
523
524
0
@@ -347,13 +347,9 @@ module ActiveCouch
0
       def find(*arguments)
0
         scope = arguments.slice!(0)
0
         search_params = arguments.slice!(0) || {}
0
- # Get the offset and limit if they exist
0
- offset = arguments.slice!(0) || {}; limit = arguments.slice!(0) || {}
0
- # Merge the offset and limit as one because the order doesn't matter
0
- options = {}.merge!(offset).merge!(limit)
0
         
0
         case scope
0
- when :all then find_every(search_params, options)
0
+ when :all then find_every(search_params)
0
           when :first then find_every(search_params, {:limit => 1}).first
0
           else find_one(scope)
0
         end
0
@@ -369,9 +365,11 @@ module ActiveCouch
0
       #
0
       # # This returns the count of the number of objects
0
       # people_count = Person.count(:params => {:name => "McLovin"})
0
- def count(params = {})
0
- result_set = find(:all, params)
0
- result_set.size
0
+ def count(search_params = {})
0
+ path = "/#{database_name}/_view/#{query_string(search_params[:params], {:limit => 0})}"
0
+ result = connection.get(path)
0
+
0
+ JSON.parse(result)['total_rows'].to_i
0
       end
0
 
0
       # Initializes a new subclass of ActiveCouch::Base and saves in the CouchDB database
0
@@ -483,11 +481,14 @@ module ActiveCouch
0
         end
0
         
0
         # Returns an array of ActiveCouch::Base objects by querying a CouchDB permanent view
0
- def find_every(search_params, options)
0
- case from = options[:from]
0
+ def find_every(search_params, overriding_options = {})
0
+ case from = search_params[:from]
0
           when String
0
             path = "#{from}"
0
           else
0
+ options = search_params.reject { |k,v| k == :params }
0
+ options.merge!(overriding_options)
0
+
0
             path = "/#{database_name}/_view/#{query_string(search_params[:params], options)}"
0
           end
0
           instantiate_collection(connection.get(path))
0
@@ -507,18 +508,17 @@ module ActiveCouch
0
         # So for example, if the params hash is :name => 'McLovin',
0
         # the view associated with it will be /by_name/by_name?key="McLovin"
0
         def query_string(search_params, options)
0
- if search_params.is_a?(Hash)
0
- raise ArgumentError, "ActiveCouch supports only one condition per query" if search_params.keys.size != 1
0
- key = search_params.keys.first
0
+ unless search_params.is_a?(Hash) || search_params.keys.size != 1
0
+ raise ArgumentError, "Wrong options for ActiveCouch::Base#find" and return
0
+ end
0
+
0
+ key = search_params.keys.first
0
             
0
- query_string = "by_#{key}/by_#{key}?key=#{search_params[key].to_s.url_encode}"
0
- query_string = "#{query_string}&startkey=#{options[:offset].to_s.url_encode}" unless options[:offset].nil?
0
- query_string = "#{query_string}&count=#{options[:limit].to_s}" unless options[:limit].nil?
0
+ query_string = "by_#{key}/by_#{key}?key=#{search_params[key].to_s.url_encode}"
0
+ query_string = "#{query_string}&skip=#{options[:offset]}" unless options[:offset].nil?
0
+ query_string = "#{query_string}&count=#{options[:limit]}" unless options[:limit].nil?
0
             
0
- query_string
0
- else
0
- raise ArgumentError, "The value for the key 'params' must be a Hash"
0
- end
0
+ query_string
0
         end
0
         
0
         # Instantiates a collection of ActiveCouch::Base objects, based on the
...
15
16
17
 
 
 
 
 
 
18
19
20
...
15
16
17
18
19
20
21
22
23
24
25
26
0
@@ -15,6 +15,12 @@ module ActiveCouch
0
     def classify; Inflector.classify(self); end
0
     def constantize; Inflector.constantize(self); end
0
   end
0
+
0
+ Array.class_eval do
0
+ def extract_options!
0
+ last.is_a?(::Hash) ? pop : {}
0
+ end
0
+ end
0
   
0
   Hash.class_eval do
0
     # Flatten on the array removes everything into *one* single array,
...
1
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
4
5
...
115
116
117
118
 
119
120
121
122
123
124
125
 
126
127
128
129
130
131
132
133
134
135
 
 
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
 
180
181
 
182
183
184
185
186
187
 
188
189
190
 
 
191
192
 
193
194
195
196
197
198
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
201
202
203
 
204
205
206
207
 
 
 
 
208
 
209
210
 
211
212
 
213
214
215
216
217
218
219
220
 
 
 
 
 
221
222
 
223
224
225
226
227
228
229
230
231
 
 
 
 
 
 
 
 
 
 
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
 
 
 
 
 
 
 
 
 
251
252
253
254
255
256
257
258
259
260
261
262
263
264
 
 
 
265
266
267
268
269
270
271
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
...
270
271
272
 
273
274
 
 
 
 
 
 
275
276
 
 
 
277
 
 
 
 
 
278
279
280
281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
284
 
285
286
287
288
289
290
 
291
292
 
 
293
294
295
 
296
297
298
299
300
301
302
 
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
 
 
319
320
321
 
 
322
323
324
325
326
327
328
 
329
330
 
331
332
333
334
335
336
 
 
 
337
338
339
340
341
342
 
343
344
345
346
347
348
349
 
 
 
350
351
352
353
354
355
356
357
358
359
360
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
363
364
365
366
367
368
369
370
371
 
 
 
 
 
 
 
 
 
 
 
 
372
373
374
375
376
 
 
 
 
 
377
0
@@ -1,5 +1,160 @@
0
 require File.dirname(__FILE__) + '/../spec_helper.rb'
0
 
0
+describe "ActiveCouch::Base #find method with an object which has associations" do
0
+ before(:each) do
0
+ class Comment < ActiveCouch::Base
0
+ site 'http://localhost:5984'
0
+ has :body
0
+ end
0
+
0
+ class Blog < ActiveCouch::Base
0
+ site 'http://localhost:5984'
0
+ has :title
0
+ has_many :comments
0
+ end
0
+
0
+ # Define the migration
0
+ class ByTitle < ActiveCouch::Migration
0
+ define :for_db => 'blogs' do
0
+ with_key 'title'
0
+ end
0
+ end
0
+
0
+ # Create the database first
0
+ ActiveCouch::Migrator.create_database('http://localhost:5984', 'blogs')
0
+ # Create a view
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByTitle)
0
+ blog = Blog.new(:title => 'iPhone in Singapore')
0
+ # Associations
0
+ blog.add_comment(Comment.new(:body => 'soon plz'))
0
+ blog.add_comment(Comment.new(:body => 'ya rly!'))
0
+ # Save the blog
0
+ blog.save
0
+ end
0
+
0
+ after(:each) do
0
+ # Create the database first
0
+ ActiveCouch::Migrator.delete_database('http://localhost:5984', 'blogs')
0
+ Object.send(:remove_const, :Blog)
0
+ Object.send(:remove_const, :Comment)
0
+ end
0
+
0
+ it "should be able to retrieve the simple attributes" do
0
+ blog = Blog.find(:first, :params => {:title => 'iPhone in Singapore'})
0
+ blog.title.should == 'iPhone in Singapore'
0
+ end
0
+
0
+ it "should be able to retrieve associations" do
0
+ blog = Blog.find(:first, :params => {:title => 'iPhone in Singapore'})
0
+ blog.comments.size.should == 2
0
+ # Check whether the bodies of the comments exist
0
+ (blog.comments.inspect =~ /soon plz/).should_not == nil
0
+ (blog.comments.inspect =~ /ya rly!/).should_not == nil
0
+ end
0
+
0
+end
0
+
0
+describe "ActiveCouch::Base #find method with no params passed" do
0
+ before(:each) do
0
+ class Person < ActiveCouch::Base
0
+ site 'http://localhost:5984/'
0
+ has :name
0
+ end
0
+ # Define the migration
0
+ class ByName < ActiveCouch::Migration
0
+ define :for_db => 'people' do
0
+ with_key 'name'
0
+ end
0
+ end
0
+ # Create the database first
0
+ ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
+ # Create a view
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByName)
0
+ # Save two objects
0
+ Person.create(:name => 'McLovin')
0
+ Person.create(:name => 'Seth')
0
+ end
0
+
0
+ after(:each) do
0
+ # Delete the database last
0
+ ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
+ Object.send(:remove_const, :Person)
0
+ end
0
+
0
+ it "should return all documents if passed :all, with no params specified"
0
+end
0
+
0
+
0
+describe "ActiveCouch::Base #find method with an ID passed" do
0
+ before(:each) do
0
+ class Person < ActiveCouch::Base
0
+ site 'http://localhost:5984/'
0
+ has :name
0
+ end
0
+ # Define the migration
0
+ class ByName < ActiveCouch::Migration
0
+ define :for_db => 'people' do
0
+ with_key 'name'
0
+ end
0
+ end
0
+ # Create the database first
0
+ ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
+ # Create a view
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByName)
0
+ # Save one object
0
+ p = Person.create(:name => 'McLovin', :id => '123')
0
+ end
0
+
0
+ after(:each) do
0
+ # Delete the database last
0
+ ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
+ Object.send(:remove_const, :Person)
0
+ end
0
+
0
+ it "should return an ActiveCouch::Base object if the ID exists" do
0
+ person = Person.find('123')
0
+ person.name.should == 'McLovin'
0
+ end
0
+
0
+ it "should return nil if the ID does not exist" do
0
+ person = Person.find('321')
0
+ person.should == nil
0
+ end
0
+end
0
+
0
+describe "ActiveCouch::Base #find method with non-String params passed as arguments" do
0
+ before(:each) do
0
+ class Person < ActiveCouch::Base
0
+ site 'http://localhost:5984/'
0
+ has :age
0
+ end
0
+ # Define the migration
0
+ class ByAge < ActiveCouch::Migration
0
+ define :for_db => 'people' do
0
+ with_key 'age'
0
+ end
0
+ end
0
+ # Create the database first
0
+ ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
+ # Create a view
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByAge)
0
+ # Save two objects
0
+ p = Person.create(:age => "21")
0
+ end
0
+
0
+ after(:each) do
0
+ # Delete the database last
0
+ ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
+ Object.send(:remove_const, :Person)
0
+ end
0
+
0
+ it "should return an ActiveCouch::Base object" do
0
+ person = Person.find(:first, :params => {:age => 21})
0
+ person.age.should == "21"
0
+ end
0
+end
0
+
0
+
0
 describe "ActiveCouch::Base #find method with just simple attributes" do
0
   before(:each) do
0
     # Define the model
0
@@ -115,156 +270,107 @@ describe "ActiveCouch::Base #find method with multiple documents in the CouchDB
0
   end
0
 end
0
 
0
-describe "ActiveCouch::Base #find method with an object which has associations" do
0
+describe "ActiveCouch::Base #find method :limit option used" do
0
   before(:each) do
0
- class Comment < ActiveCouch::Base
0
- site 'http://localhost:5984'
0
- has :body
0
- end
0
-
0
- class Blog < ActiveCouch::Base
0
+ class Person < ActiveCouch::Base
0
       site 'http://localhost:5984'
0
- has :title
0
- has_many :comments
0
- end
0
       
0
- # Define the migration
0
- class ByTitle < ActiveCouch::Migration
0
- define :for_db => 'blogs' do
0
- with_key 'title'
0
- end
0
+ has :first_name
0
+ has :last_name
0
     end
0
     
0
- # Create the database first
0
- ActiveCouch::Migrator.create_database('http://localhost:5984', 'blogs')
0
- # Create a view
0
- ActiveCouch::Migrator.migrate('http://localhost:5984', ByTitle)
0
- blog = Blog.new(:title => 'iPhone in Singapore')
0
- # Associations
0
- blog.add_comment(Comment.new(:body => 'soon plz'))
0
- blog.add_comment(Comment.new(:body => 'ya rly!'))
0
- # Save the blog
0
- blog.save
0
- end
0
-
0
- after(:each) do
0
- # Create the database first
0
- ActiveCouch::Migrator.delete_database('http://localhost:5984', 'blogs')
0
- Object.send(:remove_const, :Blog)
0
- Object.send(:remove_const, :Comment)
0
- end
0
-
0
- it "should be able to retrieve the simple attributes" do
0
- blog = Blog.find(:first, :params => {:title => 'iPhone in Singapore'})
0
- blog.title.should == 'iPhone in Singapore'
0
- end
0
-
0
- it "should be able to retrieve associations" do
0
- blog = Blog.find(:first, :params => {:title => 'iPhone in Singapore'})
0
- blog.comments.size.should == 2
0
- # Check whether the bodies of the comments exist
0
- (blog.comments.inspect =~ /soon plz/).should_not == nil
0
- (blog.comments.inspect =~ /ya rly!/).should_not == nil
0
- end
0
-
0
-end
0
-
0
-describe "ActiveCouch::Base #find method with no params passed" do
0
- before(:each) do
0
- class Person < ActiveCouch::Base
0
- site 'http://localhost:5984/'
0
- has :name
0
- end
0
     # Define the migration
0
- class ByName < ActiveCouch::Migration
0
+ class ByLastName < ActiveCouch::Migration
0
       define :for_db => 'people' do
0
- with_key 'name'
0
+ with_key 'last_name'
0
       end
0
     end
0
     # Create the database first
0
     ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
     # Create a view
0
- ActiveCouch::Migrator.migrate('http://localhost:5984', ByName)
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByLastName)
0
     # Save two objects
0
- Person.create(:name => 'McLovin')
0
- Person.create(:name => 'Seth')
0
+ Person.create(:last_name => 'McLovin', :first_name => 'Seth')
0
+ Person.create(:last_name => 'McLovin', :first_name => 'Bob')
0
   end
0
-
0
+
0
   after(:each) do
0
     # Delete the database last
0
     ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
     Object.send(:remove_const, :Person)
0
   end
0
   
0
- it "should return all documents if passed :all, with no params specified"
0
+ it "should return only one object in the database when find method is sent the param :limit => 1" do
0
+ people = Person.find(:all, :params => {:last_name => 'McLovin'}, :limit => 1)
0
+ # Check if it is an array and if the size is 2
0
+ people.class.should == Array
0
+ people.size.should == 1
0
+ # The id's and rev's for all the objects must not be nil
0
+ person = people.first
0
+ person.id.should_not == nil
0
+ person.rev.should_not == nil
0
+
0
+ person.first_name == 'Seth'
0
+ person.last_name == 'McLovin'
0
+
0
+ end
0
 end
0
 
0
-
0
-describe "ActiveCouch::Base #find method with an ID passed" do
0
+describe "ActiveCouch::Base #find method :limit and :offset options used" do
0
   before(:each) do
0
     class Person < ActiveCouch::Base
0
- site 'http://localhost:5984/'
0
- has :name
0
+ site 'http://localhost:5984'
0
+
0
+ has :first_name
0
+ has :last_name
0
     end
0
+
0
     # Define the migration
0
- class ByName < ActiveCouch::Migration
0
+ class ByLastName < ActiveCouch::Migration
0
       define :for_db => 'people' do
0
- with_key 'name'
0
+ with_key 'last_name'
0
       end
0
     end
0
     # Create the database first
0
     ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
     # Create a view
0
- ActiveCouch::Migrator.migrate('http://localhost:5984', ByName)
0
- # Save one object
0
- p = Person.create(:name => 'McLovin', :id => '123')
0
+ ActiveCouch::Migrator.migrate('http://localhost:5984', ByLastName)
0
+ # Save two objects
0
+ Person.create(:id => 'Seth', :last_name => 'McLovin', :first_name => 'Seth')
0
+ Person.create(:id => 'Bob', :last_name => 'McLovin', :first_name => 'Bob')
0
+ Person.create(:id => 'John', :last_name => 'McLovin', :first_name => 'Bob')
0
   end
0
-
0
+
0
   after(:each) do
0
     # Delete the database last
0
     ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
     Object.send(:remove_const, :Person)
0
   end
0
   
0
- it "should return an ActiveCouch::Base object if the ID exists" do
0
- person = Person.find('123')
0
- person.name.should == 'McLovin'
0
+ it "should return two objects in the database when find method is sent the param :offset => 1" do
0
+ people = Person.find(:all, :params => {:last_name => 'McLovin'}, :offset => 1)
0
+ # Check if it is an array and if the size is 2
0
+ people.class.should == Array
0
+ people.size.should == 2
0
+ # The id's and rev's for all the objects must not be nil
0
+ people.each do |p|
0
+ p.id.should_not == nil
0
+ p.rev.should_not == nil
0
+ end
0
   end
0
   
0
- it "should return nil if the ID does not exist" do
0
- person = Person.find('321')
0
- person.should == nil
0
- end
0
-end
0
-
0
-describe "ActiveCouch::Base #find method with non-String params passed as arguments" do
0
- before(:each) do
0
- class Person < ActiveCouch::Base
0
- site 'http://localhost:5984/'
0
- has :age
0
- end
0
- # Define the migration
0
- class ByAge < ActiveCouch::Migration
0
- define :for_db => 'people' do
0
- with_key 'age'
0
- end
0
+ it "should return one object in the database when find method is sent the param :offset => 1 and :limit => 1" do
0
+ people = Person.find(:all, :params => {:last_name => 'McLovin'}, :offset => 1, :limit => 1)
0
+ # Check if it is an array and if the size is 2
0
+ people.class.should == Array
0
+ people.size.should == 1
0
+ # The id's and rev's for all the objects must not be nil
0
+ people.each do |p|
0
+ p.id.should_not == nil
0
+ p.rev.should_not == nil
0
     end
0
- # Create the database first
0
- ActiveCouch::Migrator.create_database('http://localhost:5984', 'people')
0
- # Create a view
0
- ActiveCouch::Migrator.migrate('http://localhost:5984', ByAge)
0
- # Save two objects
0
- p = Person.create(:age => "21")
0
- end
0
-
0
- after(:each) do
0
- # Delete the database last
0
- ActiveCouch::Migrator.delete_database('http://localhost:5984', 'people')
0
- Object.send(:remove_const, :Person)
0
   end
0
+
0
+
0
+end
0
 
0
- it "should return an ActiveCouch::Base object" do
0
- person = Person.find(:first, :params => {:age => 21})
0
- person.age.should == "21"
0
- end
0
-end
0
\ No newline at end of file

Comments

    No one has commented yet.