mongoid 0.11.7 → 0.11.8

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 CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.11.8
2
+ - Added #min and #max to criteria which takes a
3
+ single field argument.
4
+
1
5
  === 0.11.7
2
6
  - Added #sum to criteria which takes a single field
3
7
  to aggregate on. Example: Person.sum(:age) would
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.7
1
+ 0.11.8
@@ -422,23 +422,48 @@ module Mongoid #:nodoc:
422
422
  end
423
423
 
424
424
  SUM_REDUCE = "function(obj, prev) { prev.sum += obj.[field]; }"
425
- # Sum the criteria. This will take the internally built selector and options
425
+ # Sum the criteria.
426
+ #
427
+ # This will take the internally built selector and options
426
428
  # and pass them on to the Ruby driver's +group()+ method on the collection. The
427
429
  # collection itself will be retrieved from the class provided, and once the
428
430
  # query has returned it will provided a grouping of keys with sums.
429
431
  #
430
432
  # Example:
431
433
  #
432
- # <tt>criteria.select(:field1).where(:field1 => "Title").sum</tt>
434
+ # <tt>criteria.sum(:age)</tt>
433
435
  def sum(field)
434
- collection = @klass.collection.group(
435
- @options[:fields],
436
- @selector,
437
- { :sum => 0 },
438
- SUM_REDUCE.gsub("[field]", field.to_s),
439
- true
440
- )
441
- collection.first["sum"]
436
+ grouped(:sum, field.to_s, SUM_REDUCE)
437
+ end
438
+
439
+ MIN_REDUCE = "function(obj, prev) { if (prev.max > obj.[field]) { prev.max = obj.[field]; } }"
440
+ # Return the min value for a field.
441
+ #
442
+ # This will take the internally built selector and options
443
+ # and pass them on to the Ruby driver's +group()+ method on the collection. The
444
+ # collection itself will be retrieved from the class provided, and once the
445
+ # query has returned it will provided a grouping of keys with sums.
446
+ #
447
+ # Example:
448
+ #
449
+ # <tt>criteria.min(:age)</tt>
450
+ def min(field)
451
+ grouped(:min, field.to_s, MIN_REDUCE)
452
+ end
453
+
454
+ MAX_REDUCE = "function(obj, prev) { if (prev.max < obj.[field]) { prev.max = obj.[field]; } }"
455
+ # Return the max value for a field.
456
+ #
457
+ # This will take the internally built selector and options
458
+ # and pass them on to the Ruby driver's +group()+ method on the collection. The
459
+ # collection itself will be retrieved from the class provided, and once the
460
+ # query has returned it will provided a grouping of keys with sums.
461
+ #
462
+ # Example:
463
+ #
464
+ # <tt>criteria.max(:age)</tt>
465
+ def max(field)
466
+ grouped(:max, field.to_s, MAX_REDUCE)
442
467
  end
443
468
 
444
469
  # Translate the supplied arguments into a +Criteria+ object.
@@ -536,5 +561,18 @@ module Mongoid #:nodoc:
536
561
  def update_selector(attributes, operator)
537
562
  attributes.each { |key, value| @selector[key] = { operator => value } }; self
538
563
  end
564
+
565
+ # Common functionality for grouping operations. Currently used by min, max
566
+ # and sum. Will gsub the field name in the supplied reduce function.
567
+ def grouped(start, field, reduce)
568
+ collection = @klass.collection.group(
569
+ nil,
570
+ @selector,
571
+ { start => 0 },
572
+ reduce.gsub("[field]", field),
573
+ true
574
+ )
575
+ collection.first[start.to_s]
576
+ end
539
577
  end
540
578
  end
@@ -5,7 +5,8 @@ module Mongoid #:nodoc:
5
5
  module Conversions #:nodoc:
6
6
  def set(value)
7
7
  return nil if value.blank?
8
- ::Time.parse(value.to_s).utc
8
+ time = ::Time.parse(value.to_s)
9
+ time.utc? ? time : time.utc
9
10
  end
10
11
  def get(value)
11
12
  return nil if value.blank?
@@ -76,6 +76,21 @@ module Mongoid #:nodoc:
76
76
  find(:last, *args)
77
77
  end
78
78
 
79
+ # Convenience method for returning the max value of a field.
80
+ #
81
+ # Options:
82
+ #
83
+ # field: The field to use when calculating the max.
84
+ #
85
+ # Example:
86
+ #
87
+ # <tt>Person.max(:age)</tt>
88
+ #
89
+ # Returns: <tt>Float</tt> max value.
90
+ def max(field)
91
+ Criteria.new(self).max(field)
92
+ end
93
+
79
94
  # Will execute a +Criteria+ based on the +DynamicFinder+ that gets
80
95
  # generated.
81
96
  #
@@ -94,6 +109,21 @@ module Mongoid #:nodoc:
94
109
  results ? results : dyna.create(self)
95
110
  end
96
111
 
112
+ # Convenience method for returning the min value of a field.
113
+ #
114
+ # Options:
115
+ #
116
+ # field: The field to use when calculating the min.
117
+ #
118
+ # Example:
119
+ #
120
+ # <tt>Person.min(:age)</tt>
121
+ #
122
+ # Returns: <tt>Float</tt> min value.
123
+ def min(field)
124
+ Criteria.new(self).min(field)
125
+ end
126
+
97
127
  # Find all documents in paginated fashion given the supplied arguments.
98
128
  # If no parameters are passed just default to offset 0 and limit 20.
99
129
  #
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid}
8
- s.version = "0.11.7"
8
+ s.version = "0.11.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Durran Jordan"]
@@ -2,6 +2,42 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Criteria do
4
4
 
5
+ describe "#max" do
6
+
7
+ before do
8
+ 10.times do |n|
9
+ Person.create(:title => "Sir", :age => (n * 10), :aliases => ["D", "Durran"])
10
+ end
11
+ end
12
+
13
+ after do
14
+ Person.delete_all
15
+ end
16
+
17
+ it "provides sums for all the fields provided" do
18
+ Person.criteria.max(:age).should == 90.0
19
+ end
20
+
21
+ end
22
+
23
+ describe "#min" do
24
+
25
+ before do
26
+ 10.times do |n|
27
+ Person.create(:title => "Sir", :age => (n * 10), :aliases => ["D", "Durran"])
28
+ end
29
+ end
30
+
31
+ after do
32
+ Person.delete_all
33
+ end
34
+
35
+ it "provides sums for all the fields provided" do
36
+ Person.criteria.min(:age).should == 0.0
37
+ end
38
+
39
+ end
40
+
5
41
  describe "#sum" do
6
42
 
7
43
  before do
@@ -492,6 +492,27 @@ describe Mongoid::Criteria do
492
492
 
493
493
  end
494
494
 
495
+ describe "#max" do
496
+
497
+ before do
498
+ @reduce = "function(obj, prev) { if (prev.max < obj.age) { prev.max = obj.age; } }"
499
+ @collection = mock
500
+ Person.expects(:collection).returns(@collection)
501
+ end
502
+
503
+ it "calls group on the collection with the aggregate js" do
504
+ @collection.expects(:group).with(
505
+ nil,
506
+ {:_type => { "$in" => ["Doctor", "Person"] } },
507
+ {:max => 0},
508
+ @reduce,
509
+ true
510
+ ).returns([{"max" => 200.0}])
511
+ @criteria.max(:age).should == 200.0
512
+ end
513
+
514
+ end
515
+
495
516
  describe "#merge" do
496
517
 
497
518
  before do
@@ -591,11 +612,36 @@ describe Mongoid::Criteria do
591
612
 
592
613
  end
593
614
 
615
+ describe "#min" do
616
+
617
+ before do
618
+ @reduce = "function(obj, prev) { if (prev.max > obj.age) { prev.max = obj.age; } }"
619
+ @collection = mock
620
+ Person.expects(:collection).returns(@collection)
621
+ end
622
+
623
+ it "calls group on the collection with the aggregate js" do
624
+ @collection.expects(:group).with(
625
+ nil,
626
+ {:_type => { "$in" => ["Doctor", "Person"] } },
627
+ {:min => 0},
628
+ @reduce,
629
+ true
630
+ ).returns([{"min" => 4.0}])
631
+ @criteria.min(:age).should == 4.0
632
+ end
633
+
634
+ end
635
+
594
636
  describe "#not_in" do
595
637
 
596
638
  it "adds the exclusion to the selector" do
597
639
  @criteria.not_in(:title => ["title1", "title2"], :text => ["test"])
598
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$nin" => ["title1", "title2"] }, :text => { "$nin" => ["test"] } }
640
+ @criteria.selector.should == {
641
+ :_type => { "$in" => ["Doctor", "Person"] },
642
+ :title => { "$nin" => ["title1", "title2"] },
643
+ :text => { "$nin" => ["test"] }
644
+ }
599
645
  end
600
646
 
601
647
  it "returns self" do
@@ -851,8 +897,14 @@ describe Mongoid::Criteria do
851
897
  end
852
898
 
853
899
  it "calls group on the collection with the aggregate js" do
854
- @collection.expects(:group).with(nil, {:_type => { "$in" => ["Doctor", "Person"] }}, {:sum => 0}, @reduce, true).returns([{"sum" => 50.0}])
855
- @criteria.sum(:age)
900
+ @collection.expects(:group).with(
901
+ nil,
902
+ {:_type => { "$in" => ["Doctor", "Person"] } },
903
+ {:sum => 0},
904
+ @reduce,
905
+ true
906
+ ).returns([{"sum" => 50.0}])
907
+ @criteria.sum(:age).should == 50.0
856
908
  end
857
909
 
858
910
  end
@@ -29,6 +29,14 @@ describe Mongoid::Extensions::Time::Conversions do
29
29
 
30
30
  end
31
31
 
32
+ context "when value is already a utc time" do
33
+
34
+ it "returns the time" do
35
+ Time.set(@time.utc).should == @time.utc
36
+ end
37
+
38
+ end
39
+
32
40
  context "when value is nil" do
33
41
 
34
42
  it "returns nil" do
@@ -197,6 +197,20 @@ describe Mongoid::Finders do
197
197
 
198
198
  end
199
199
 
200
+ describe ".max" do
201
+
202
+ before do
203
+ @criteria = mock
204
+ end
205
+
206
+ it "returns the sum of a new criteria" do
207
+ Mongoid::Criteria.expects(:new).returns(@criteria)
208
+ @criteria.expects(:max).with(:age).returns(50.0)
209
+ Person.max(:age).should == 50.0
210
+ end
211
+
212
+ end
213
+
200
214
  describe ".method_missing" do
201
215
 
202
216
  context "with a finder method name" do
@@ -250,6 +264,20 @@ describe Mongoid::Finders do
250
264
 
251
265
  end
252
266
 
267
+ describe ".min" do
268
+
269
+ before do
270
+ @criteria = mock
271
+ end
272
+
273
+ it "returns the sum of a new criteria" do
274
+ Mongoid::Criteria.expects(:new).returns(@criteria)
275
+ @criteria.expects(:min).with(:age).returns(50.0)
276
+ Person.min(:age).should == 50.0
277
+ end
278
+
279
+ end
280
+
253
281
  describe ".paginate" do
254
282
 
255
283
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.7
4
+ version: 0.11.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Durran Jordan