mongoid 0.11.6 → 0.11.7
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +13 -0
- data/VERSION +1 -1
- data/lib/mongoid.rb +2 -0
- data/lib/mongoid/associations.rb +8 -13
- data/lib/mongoid/criteria.rb +31 -8
- data/lib/mongoid/document.rb +1 -1
- data/lib/mongoid/finders.rb +16 -0
- data/lib/mongoid/memoization.rb +27 -0
- data/mongoid.gemspec +5 -2
- data/perf/benchmark.rb +24 -23
- data/spec/integration/mongoid/criteria_spec.rb +23 -5
- data/spec/integration/mongoid/inheritance_spec.rb +18 -0
- data/spec/unit/mongoid/attributes_spec.rb +1 -0
- data/spec/unit/mongoid/criteria_spec.rb +54 -25
- data/spec/unit/mongoid/finders_spec.rb +15 -0
- data/spec/unit/mongoid/memoization_spec.rb +75 -0
- metadata +5 -2
data/HISTORY
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 0.11.7
|
2
|
+
- Added #sum to criteria which takes a single field
|
3
|
+
to aggregate on. Example: Person.sum(:age) would
|
4
|
+
return a float that was the sum of all people's
|
5
|
+
ages in the db.
|
6
|
+
|
7
|
+
- Fixed issue with queries from parent classes always
|
8
|
+
casting the returned documents to the parent.
|
9
|
+
|
10
|
+
- Fixed singleton require issue.
|
11
|
+
|
12
|
+
- Group queries now run as db commands
|
13
|
+
|
1
14
|
=== 0.11.6
|
2
15
|
- Allow namespaced documents to default with:
|
3
16
|
"namespace_modelname"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.11.
|
1
|
+
0.11.7
|
data/lib/mongoid.rb
CHANGED
@@ -28,6 +28,7 @@ gem "leshill-will_paginate", ">= 2.3.11"
|
|
28
28
|
|
29
29
|
require "delegate"
|
30
30
|
require "observer"
|
31
|
+
require "singleton"
|
31
32
|
require "time"
|
32
33
|
require "validatable"
|
33
34
|
require "active_support/callbacks"
|
@@ -48,6 +49,7 @@ require "mongoid/extensions"
|
|
48
49
|
require "mongoid/errors"
|
49
50
|
require "mongoid/field"
|
50
51
|
require "mongoid/finders"
|
52
|
+
require "mongoid/memoization"
|
51
53
|
require "mongoid/timestamps"
|
52
54
|
require "mongoid/versioning"
|
53
55
|
require "mongoid/document"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -11,6 +11,10 @@ module Mongoid # :nodoc:
|
|
11
11
|
module Associations #:nodoc:
|
12
12
|
def self.included(base)
|
13
13
|
base.class_eval do
|
14
|
+
# Associations need to inherit down the chain.
|
15
|
+
class_inheritable_accessor :associations
|
16
|
+
self.associations = {}.with_indifferent_access
|
17
|
+
|
14
18
|
include InstanceMethods
|
15
19
|
extend ClassMethods
|
16
20
|
end
|
@@ -35,9 +39,6 @@ module Mongoid # :nodoc:
|
|
35
39
|
end
|
36
40
|
|
37
41
|
module ClassMethods
|
38
|
-
def associations
|
39
|
-
@associations ||= {}.with_indifferent_access
|
40
|
-
end
|
41
42
|
# Adds the association back to the parent document. This macro is
|
42
43
|
# necessary to set the references from the child back to the parent
|
43
44
|
# document. If a child does not define this association calling
|
@@ -198,22 +199,16 @@ module Mongoid # :nodoc:
|
|
198
199
|
|
199
200
|
protected
|
200
201
|
# Adds the association to the associations hash with the type as the key,
|
201
|
-
# then adds the accessors for the association.
|
202
|
+
# then adds the accessors for the association. The defined setters and
|
203
|
+
# getters for the associations will perform the necessary memoization.
|
202
204
|
def add_association(type, options)
|
203
205
|
name = options.name
|
204
206
|
associations[name] = type
|
205
207
|
define_method(name) do
|
206
|
-
|
207
|
-
proxy = type.instantiate(self, options)
|
208
|
-
instance_variable_set("@#{name}", proxy)
|
208
|
+
memoized(name) { type.instantiate(self, options) }
|
209
209
|
end
|
210
210
|
define_method("#{name}=") do |object|
|
211
|
-
|
212
|
-
if instance_variable_defined?("@#{name}")
|
213
|
-
remove_instance_variable("@#{name}")
|
214
|
-
else
|
215
|
-
instance_variable_set("@#{name}", proxy)
|
216
|
-
end
|
211
|
+
reset(name) { type.update(object, self, options) }
|
217
212
|
end
|
218
213
|
end
|
219
214
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -48,9 +48,8 @@ module Mongoid #:nodoc:
|
|
48
48
|
# Example:
|
49
49
|
#
|
50
50
|
# <tt>criteria.select(:field1).where(:field1 => "Title").aggregate(Person)</tt>
|
51
|
-
def aggregate
|
52
|
-
@klass
|
53
|
-
@klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE)
|
51
|
+
def aggregate
|
52
|
+
@klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE, true)
|
54
53
|
end
|
55
54
|
|
56
55
|
# Adds a criterion to the +Criteria+ that specifies values that must all
|
@@ -165,9 +164,13 @@ module Mongoid #:nodoc:
|
|
165
164
|
@options[:fields],
|
166
165
|
@selector,
|
167
166
|
{ :group => [] },
|
168
|
-
GROUP_REDUCE
|
167
|
+
GROUP_REDUCE,
|
168
|
+
true
|
169
169
|
).collect do |docs|
|
170
|
-
docs["group"] = docs["group"].collect
|
170
|
+
docs["group"] = docs["group"].collect do |attrs|
|
171
|
+
attrs["_type"].constantize.instantiate(attrs)
|
172
|
+
end
|
173
|
+
docs
|
171
174
|
end
|
172
175
|
end
|
173
176
|
|
@@ -230,7 +233,7 @@ module Mongoid #:nodoc:
|
|
230
233
|
sorting = [[:_id, :asc]] unless sorting
|
231
234
|
opts[:sort] = sorting.collect { |option| [ option[0], option[1].invert ] }
|
232
235
|
attributes = @klass.collection.find_one(@selector, opts)
|
233
|
-
attributes ?
|
236
|
+
attributes ? attributes["_type"].constantize.instantiate(attributes) : nil
|
234
237
|
end
|
235
238
|
|
236
239
|
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
@@ -338,7 +341,7 @@ module Mongoid #:nodoc:
|
|
338
341
|
# <tt>Criteria.select(:name).where(:name = "Chrissy").one</tt>
|
339
342
|
def one
|
340
343
|
attributes = @klass.collection.find_one(@selector, @options.dup)
|
341
|
-
attributes ?
|
344
|
+
attributes ? attributes["_type"].constantize.instantiate(attributes) : nil
|
342
345
|
end
|
343
346
|
|
344
347
|
alias :first :one
|
@@ -418,6 +421,26 @@ module Mongoid #:nodoc:
|
|
418
421
|
@options[:skip] = value; self
|
419
422
|
end
|
420
423
|
|
424
|
+
SUM_REDUCE = "function(obj, prev) { prev.sum += obj.[field]; }"
|
425
|
+
# Sum the criteria. This will take the internally built selector and options
|
426
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
427
|
+
# collection itself will be retrieved from the class provided, and once the
|
428
|
+
# query has returned it will provided a grouping of keys with sums.
|
429
|
+
#
|
430
|
+
# Example:
|
431
|
+
#
|
432
|
+
# <tt>criteria.select(:field1).where(:field1 => "Title").sum</tt>
|
433
|
+
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"]
|
442
|
+
end
|
443
|
+
|
421
444
|
# Translate the supplied arguments into a +Criteria+ object.
|
422
445
|
#
|
423
446
|
# If the passed in args is a single +String+, then it will
|
@@ -490,7 +513,7 @@ module Mongoid #:nodoc:
|
|
490
513
|
attributes = @klass.collection.find(@selector, @options.dup)
|
491
514
|
if attributes
|
492
515
|
@count = attributes.count
|
493
|
-
attributes.collect { |doc|
|
516
|
+
attributes.collect { |doc| doc["_type"].constantize.instantiate(doc) }
|
494
517
|
else
|
495
518
|
[]
|
496
519
|
end
|
data/lib/mongoid/document.rb
CHANGED
@@ -4,7 +4,7 @@ module Mongoid #:nodoc:
|
|
4
4
|
def self.included(base)
|
5
5
|
base.class_eval do
|
6
6
|
include ActiveSupport::Callbacks
|
7
|
-
include Associations, Attributes, Commands, Observable, Validatable
|
7
|
+
include Associations, Attributes, Commands, Memoization, Observable, Validatable
|
8
8
|
include InstanceMethods
|
9
9
|
|
10
10
|
extend ClassMethods
|
data/lib/mongoid/finders.rb
CHANGED
@@ -128,6 +128,22 @@ module Mongoid #:nodoc:
|
|
128
128
|
Criteria.new(self).only(*args)
|
129
129
|
end
|
130
130
|
|
131
|
+
# Convenience method for returning the sum of a specified field for all
|
132
|
+
# documents in the database.
|
133
|
+
#
|
134
|
+
# Options:
|
135
|
+
#
|
136
|
+
# field: The field to use when calculating the sum.
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
#
|
140
|
+
# <tt>Person.sum(:age)</tt>
|
141
|
+
#
|
142
|
+
# Returns: <tt>Float</tt> of the sum.
|
143
|
+
def sum(field)
|
144
|
+
Criteria.new(self).sum(field)
|
145
|
+
end
|
146
|
+
|
131
147
|
# Entry point for creating a new criteria from a Document. This will
|
132
148
|
# instantiate a new +Criteria+ object with the supplied select criterion
|
133
149
|
# already added to it.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mongoid #:nodoc
|
2
|
+
module Memoization
|
3
|
+
|
4
|
+
# Handles cases when accessing an association that should be memoized in
|
5
|
+
# the Mongoid specific manner.
|
6
|
+
def memoized(name, &block)
|
7
|
+
var = "@#{name}"
|
8
|
+
if instance_variable_defined?(var)
|
9
|
+
return instance_variable_get(var)
|
10
|
+
end
|
11
|
+
value = yield
|
12
|
+
instance_variable_set(var, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Mongoid specific behavior is to remove the memoized object when setting
|
16
|
+
# the association, or if it wasn't previously memoized it will get set.
|
17
|
+
def reset(name, &block)
|
18
|
+
var = "@#{name}"
|
19
|
+
value = yield
|
20
|
+
if instance_variable_defined?(var)
|
21
|
+
remove_instance_variable(var)
|
22
|
+
else
|
23
|
+
instance_variable_set(var, value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/mongoid.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid}
|
8
|
-
s.version = "0.11.
|
8
|
+
s.version = "0.11.7"
|
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"]
|
12
|
-
s.date = %q{2010-01-
|
12
|
+
s.date = %q{2010-01-06}
|
13
13
|
s.email = %q{durran@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.textile"
|
@@ -68,6 +68,7 @@ Gem::Specification.new do |s|
|
|
68
68
|
"lib/mongoid/extensions/time/conversions.rb",
|
69
69
|
"lib/mongoid/field.rb",
|
70
70
|
"lib/mongoid/finders.rb",
|
71
|
+
"lib/mongoid/memoization.rb",
|
71
72
|
"lib/mongoid/timestamps.rb",
|
72
73
|
"lib/mongoid/versioning.rb",
|
73
74
|
"mongoid.gemspec",
|
@@ -121,6 +122,7 @@ Gem::Specification.new do |s|
|
|
121
122
|
"spec/unit/mongoid/extensions/time/conversions_spec.rb",
|
122
123
|
"spec/unit/mongoid/field_spec.rb",
|
123
124
|
"spec/unit/mongoid/finders_spec.rb",
|
125
|
+
"spec/unit/mongoid/memoization_spec.rb",
|
124
126
|
"spec/unit/mongoid/timestamps_spec.rb",
|
125
127
|
"spec/unit/mongoid/versioning_spec.rb",
|
126
128
|
"spec/unit/mongoid_spec.rb"
|
@@ -179,6 +181,7 @@ Gem::Specification.new do |s|
|
|
179
181
|
"spec/unit/mongoid/extensions/time/conversions_spec.rb",
|
180
182
|
"spec/unit/mongoid/field_spec.rb",
|
181
183
|
"spec/unit/mongoid/finders_spec.rb",
|
184
|
+
"spec/unit/mongoid/memoization_spec.rb",
|
182
185
|
"spec/unit/mongoid/timestamps_spec.rb",
|
183
186
|
"spec/unit/mongoid/versioning_spec.rb",
|
184
187
|
"spec/unit/mongoid_spec.rb"
|
data/perf/benchmark.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "ruby-prof"
|
3
|
+
require "benchmark"
|
3
4
|
require "mongoid"
|
4
5
|
|
5
6
|
connection = Mongo::Connection.new
|
@@ -10,7 +11,6 @@ Mongoid.database.collection("people").drop
|
|
10
11
|
class Person
|
11
12
|
include Mongoid::Document
|
12
13
|
include Mongoid::Timestamps
|
13
|
-
include Mongoid::Versioning
|
14
14
|
field :birth_date, :type => Date
|
15
15
|
has_one :name
|
16
16
|
has_one :address
|
@@ -19,7 +19,6 @@ end
|
|
19
19
|
|
20
20
|
class Name
|
21
21
|
include Mongoid::Document
|
22
|
-
include Mongoid::Timestamps
|
23
22
|
field :given
|
24
23
|
field :family
|
25
24
|
field :middle
|
@@ -28,7 +27,6 @@ end
|
|
28
27
|
|
29
28
|
class Address
|
30
29
|
include Mongoid::Document
|
31
|
-
include Mongoid::Timestamps
|
32
30
|
field :street
|
33
31
|
field :city
|
34
32
|
field :state
|
@@ -39,36 +37,39 @@ end
|
|
39
37
|
|
40
38
|
class Phone
|
41
39
|
include Mongoid::Document
|
42
|
-
include Mongoid::Timestamps
|
43
40
|
field :country_code, :type => Integer
|
44
41
|
field :number
|
45
42
|
field :phone_type
|
46
43
|
belongs_to :person, :inverse_of => :phones
|
47
44
|
end
|
48
45
|
|
49
|
-
RubyProf.start
|
46
|
+
# RubyProf.start
|
50
47
|
|
51
48
|
puts "Starting benchmark..."
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
50
|
+
Benchmark.bm do |bm|
|
51
|
+
bm.report("Mongoid") do
|
52
|
+
10000.times do |n|
|
53
|
+
person = Person.new(:birth_date => Date.new(1970, 1, 1))
|
54
|
+
name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
|
55
|
+
address = Address.new(
|
56
|
+
:street => "1 Starfleet Command Way",
|
57
|
+
:city => "San Francisco",
|
58
|
+
:state => "CA",
|
59
|
+
:post_code => "94133",
|
60
|
+
:type => "Work"
|
61
|
+
)
|
62
|
+
phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
|
63
|
+
person.name = name
|
64
|
+
person.address = address
|
65
|
+
person.phones << phone
|
66
|
+
person.save
|
67
|
+
end
|
68
|
+
end
|
68
69
|
end
|
69
70
|
|
70
|
-
result = RubyProf.stop
|
71
|
-
printer = RubyProf::FlatPrinter.new(result)
|
72
|
-
printer.print(STDOUT, 0)
|
71
|
+
# result = RubyProf.stop
|
72
|
+
# printer = RubyProf::FlatPrinter.new(result)
|
73
|
+
# printer.print(STDOUT, 0)
|
73
74
|
|
74
75
|
# Mongoid.database.collection("people").drop
|
@@ -2,16 +2,34 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Mongoid::Criteria do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe "#sum" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
10.times do |n|
|
9
|
+
Person.create(:title => "Sir", :age => 5, :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.where(:age.gt => 3).sum(:age).should == 50.0
|
19
|
+
end
|
8
20
|
|
9
|
-
after do
|
10
|
-
Person.delete_all
|
11
21
|
end
|
12
22
|
|
13
23
|
describe "#where" do
|
14
24
|
|
25
|
+
before do
|
26
|
+
@person = Person.create(:title => "Sir", :age => 33, :aliases => ["D", "Durran"])
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
Person.delete_all
|
31
|
+
end
|
32
|
+
|
15
33
|
context "with complex criterion" do
|
16
34
|
|
17
35
|
context "#all" do
|
@@ -87,6 +87,24 @@ describe Mongoid::Document do
|
|
87
87
|
|
88
88
|
end
|
89
89
|
|
90
|
+
context "when document has subclasses" do
|
91
|
+
|
92
|
+
before do
|
93
|
+
@firefox = Firefox.create(:name => "firefox")
|
94
|
+
end
|
95
|
+
|
96
|
+
after do
|
97
|
+
Firefox.delete_all
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns subclasses for querying parents" do
|
101
|
+
firefox = Canvas.where(:name => "firefox").first
|
102
|
+
firefox.should be_a_kind_of(Firefox)
|
103
|
+
firefox.should == @firefox
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
90
108
|
context "deleting subclasses" do
|
91
109
|
|
92
110
|
before do
|
@@ -4,6 +4,7 @@ describe Mongoid::Criteria do
|
|
4
4
|
|
5
5
|
before do
|
6
6
|
@criteria = Mongoid::Criteria.new(Person)
|
7
|
+
@canvas_criteria = Mongoid::Criteria.new(Canvas)
|
7
8
|
end
|
8
9
|
|
9
10
|
describe "#[]" do
|
@@ -32,22 +33,6 @@ describe Mongoid::Criteria do
|
|
32
33
|
|
33
34
|
describe "#aggregate" do
|
34
35
|
|
35
|
-
context "when klass provided" do
|
36
|
-
|
37
|
-
before do
|
38
|
-
@reduce = "function(obj, prev) { prev.count++; }"
|
39
|
-
@criteria = Mongoid::Criteria.new(Person)
|
40
|
-
@collection = mock
|
41
|
-
Person.expects(:collection).returns(@collection)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "calls group on the collection with the aggregate js" do
|
45
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce)
|
46
|
-
@criteria.only(:field1).aggregate
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
36
|
context "when klass not provided" do
|
52
37
|
|
53
38
|
before do
|
@@ -57,8 +42,8 @@ describe Mongoid::Criteria do
|
|
57
42
|
end
|
58
43
|
|
59
44
|
it "calls group on the collection with the aggregate js" do
|
60
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce)
|
61
|
-
@criteria.only(:field1).aggregate
|
45
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce, true)
|
46
|
+
@criteria.only(:field1).aggregate
|
62
47
|
end
|
63
48
|
|
64
49
|
end
|
@@ -246,7 +231,9 @@ describe Mongoid::Criteria do
|
|
246
231
|
before do
|
247
232
|
@collection = mock
|
248
233
|
Person.expects(:collection).returns(@collection)
|
249
|
-
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
234
|
+
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
235
|
+
{ "title" => "Sir", "_type" => "Person" }
|
236
|
+
)
|
250
237
|
end
|
251
238
|
|
252
239
|
it "calls find on the collection with the selector and options" do
|
@@ -271,6 +258,23 @@ describe Mongoid::Criteria do
|
|
271
258
|
|
272
259
|
end
|
273
260
|
|
261
|
+
context "when document is a subclass of the class queried from" do
|
262
|
+
|
263
|
+
before do
|
264
|
+
@collection = mock
|
265
|
+
Canvas.expects(:collection).returns(@collection)
|
266
|
+
@collection.expects(:find_one).with(@canvas_criteria.selector, @canvas_criteria.options).returns(
|
267
|
+
{ "name" => "Firefox", "_type" => "Firefox" }
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "instantiates the subclass" do
|
272
|
+
criteria = Mongoid::Criteria.new(Canvas)
|
273
|
+
criteria.first.should be_a_kind_of(Firefox)
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
274
278
|
end
|
275
279
|
|
276
280
|
describe "#excludes" do
|
@@ -335,7 +339,7 @@ describe Mongoid::Criteria do
|
|
335
339
|
describe "#group" do
|
336
340
|
|
337
341
|
before do
|
338
|
-
@grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30 }] }]
|
342
|
+
@grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30, "_type" => "Person" }] }]
|
339
343
|
end
|
340
344
|
|
341
345
|
context "when klass provided" do
|
@@ -348,7 +352,7 @@ describe Mongoid::Criteria do
|
|
348
352
|
end
|
349
353
|
|
350
354
|
it "calls group on the collection with the aggregate js" do
|
351
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce).returns(@grouping)
|
355
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce, true).returns(@grouping)
|
352
356
|
@criteria.only(:field1).group
|
353
357
|
end
|
354
358
|
|
@@ -363,7 +367,7 @@ describe Mongoid::Criteria do
|
|
363
367
|
end
|
364
368
|
|
365
369
|
it "calls group on the collection with the aggregate js" do
|
366
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce).returns(@grouping)
|
370
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce, true).returns(@grouping)
|
367
371
|
@criteria.only(:field1).group
|
368
372
|
end
|
369
373
|
|
@@ -415,7 +419,9 @@ describe Mongoid::Criteria do
|
|
415
419
|
before do
|
416
420
|
@collection = mock
|
417
421
|
Person.expects(:collection).returns(@collection)
|
418
|
-
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns(
|
422
|
+
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns(
|
423
|
+
{ "title" => "Sir", "_type" => "Person" }
|
424
|
+
)
|
419
425
|
end
|
420
426
|
|
421
427
|
it "calls find on the collection with the selector and sort options reversed" do
|
@@ -446,7 +452,9 @@ describe Mongoid::Criteria do
|
|
446
452
|
before do
|
447
453
|
@collection = mock
|
448
454
|
Person.expects(:collection).returns(@collection)
|
449
|
-
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(
|
455
|
+
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(
|
456
|
+
{ "title" => "Sir", "_type" => "Person" }
|
457
|
+
)
|
450
458
|
end
|
451
459
|
|
452
460
|
it "defaults to sort by id" do
|
@@ -661,7 +669,9 @@ describe Mongoid::Criteria do
|
|
661
669
|
before do
|
662
670
|
@collection = mock
|
663
671
|
Person.expects(:collection).returns(@collection)
|
664
|
-
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
672
|
+
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
673
|
+
{ "title"=> "Sir", "_type" => "Person" }
|
674
|
+
)
|
665
675
|
end
|
666
676
|
|
667
677
|
it "calls find on the collection with the selector and options" do
|
@@ -830,6 +840,25 @@ describe Mongoid::Criteria do
|
|
830
840
|
|
831
841
|
end
|
832
842
|
|
843
|
+
describe "#sum" do
|
844
|
+
|
845
|
+
context "when klass not provided" do
|
846
|
+
|
847
|
+
before do
|
848
|
+
@reduce = "function(obj, prev) { prev.sum += obj.age; }"
|
849
|
+
@collection = mock
|
850
|
+
Person.expects(:collection).returns(@collection)
|
851
|
+
end
|
852
|
+
|
853
|
+
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)
|
856
|
+
end
|
857
|
+
|
858
|
+
end
|
859
|
+
|
860
|
+
end
|
861
|
+
|
833
862
|
describe ".translate" do
|
834
863
|
|
835
864
|
context "with a single argument" do
|
@@ -295,6 +295,21 @@ describe Mongoid::Finders do
|
|
295
295
|
|
296
296
|
end
|
297
297
|
|
298
|
+
describe ".sum" do
|
299
|
+
|
300
|
+
before do
|
301
|
+
@criteria = mock
|
302
|
+
end
|
303
|
+
|
304
|
+
it "returns the sum of a new criteria" do
|
305
|
+
Mongoid::Criteria.expects(:new).returns(@criteria)
|
306
|
+
@criteria.expects(:sum).with(:age).returns(50.0)
|
307
|
+
sum = Person.sum(:age)
|
308
|
+
sum.should == 50.0
|
309
|
+
end
|
310
|
+
|
311
|
+
end
|
312
|
+
|
298
313
|
describe ".where" do
|
299
314
|
|
300
315
|
it "returns a new criteria with select conditions added" do
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Memoization do
|
4
|
+
|
5
|
+
let(:memo) { "Memo" }
|
6
|
+
|
7
|
+
before do
|
8
|
+
@person = Person.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#memoized" do
|
12
|
+
|
13
|
+
context "when variable has been defined" do
|
14
|
+
|
15
|
+
before do
|
16
|
+
@person.instance_variable_set("@memo", memo)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns the memoized value" do
|
20
|
+
@person.memoized(:memo) { nil }.should == memo
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when variable has not been defined" do
|
26
|
+
|
27
|
+
it "returns the new value" do
|
28
|
+
@person.memoized(:memo) { memo }.should == memo
|
29
|
+
end
|
30
|
+
|
31
|
+
it "memoizes the new value" do
|
32
|
+
@person.memoized(:memo) { memo }
|
33
|
+
@person.instance_variable_get("@memo").should == memo
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#reset" do
|
41
|
+
|
42
|
+
context "when variable has been defined" do
|
43
|
+
|
44
|
+
before do
|
45
|
+
@person.instance_variable_set("@memo", memo)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "removes the memoized value" do
|
49
|
+
@person.reset(:memo) { nil }
|
50
|
+
@person.instance_variable_defined?("@memo").should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the new value" do
|
54
|
+
@person.reset(:memo) { memo }.should == memo
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when variable has not been defined" do
|
60
|
+
|
61
|
+
it "memoizes the new value" do
|
62
|
+
@person.reset(:memo) { memo }
|
63
|
+
@person.instance_variable_get("@memo").should == memo
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns the value" do
|
67
|
+
@person.reset(:memo) { memo }.should == memo
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
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.
|
4
|
+
version: 0.11.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Durran Jordan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-06 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- lib/mongoid/extensions/time/conversions.rb
|
135
135
|
- lib/mongoid/field.rb
|
136
136
|
- lib/mongoid/finders.rb
|
137
|
+
- lib/mongoid/memoization.rb
|
137
138
|
- lib/mongoid/timestamps.rb
|
138
139
|
- lib/mongoid/versioning.rb
|
139
140
|
- mongoid.gemspec
|
@@ -187,6 +188,7 @@ files:
|
|
187
188
|
- spec/unit/mongoid/extensions/time/conversions_spec.rb
|
188
189
|
- spec/unit/mongoid/field_spec.rb
|
189
190
|
- spec/unit/mongoid/finders_spec.rb
|
191
|
+
- spec/unit/mongoid/memoization_spec.rb
|
190
192
|
- spec/unit/mongoid/timestamps_spec.rb
|
191
193
|
- spec/unit/mongoid/versioning_spec.rb
|
192
194
|
- spec/unit/mongoid_spec.rb
|
@@ -267,6 +269,7 @@ test_files:
|
|
267
269
|
- spec/unit/mongoid/extensions/time/conversions_spec.rb
|
268
270
|
- spec/unit/mongoid/field_spec.rb
|
269
271
|
- spec/unit/mongoid/finders_spec.rb
|
272
|
+
- spec/unit/mongoid/memoization_spec.rb
|
270
273
|
- spec/unit/mongoid/timestamps_spec.rb
|
271
274
|
- spec/unit/mongoid/versioning_spec.rb
|
272
275
|
- spec/unit/mongoid_spec.rb
|