mongoid 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/mongoid/collection.rb +42 -30
- data/lib/mongoid/collections/operations.rb +2 -0
- data/lib/mongoid/config.rb +0 -2
- data/lib/mongoid/contexts/mongo.rb +3 -3
- data/lib/mongoid/criteria.rb +28 -20
- data/lib/mongoid/criterion/optional.rb +32 -0
- data/lib/mongoid/cursor.rb +6 -6
- data/lib/mongoid/document.rb +8 -13
- data/lib/mongoid/factory.rb +4 -2
- data/mongoid.gemspec +2 -2
- data/spec/integration/mongoid/criteria_spec.rb +16 -24
- data/spec/integration/mongoid/document_spec.rb +7 -0
- data/spec/unit/mongoid/collection_spec.rb +61 -33
- data/spec/unit/mongoid/contexts/mongo_spec.rb +3 -1
- data/spec/unit/mongoid/criteria_spec.rb +24 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +55 -0
- data/spec/unit/mongoid/cursor_spec.rb +1 -1
- data/spec/unit/mongoid/document_spec.rb +17 -4
- data/spec/unit/mongoid/factory_spec.rb +20 -5
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.4
|
data/lib/mongoid/collection.rb
CHANGED
@@ -16,16 +16,7 @@ module Mongoid #:nodoc
|
|
16
16
|
# Example:
|
17
17
|
#
|
18
18
|
# <tt>collection.save({ :name => "Al" })</tt>
|
19
|
-
proxy(:master, Collections::Operations::
|
20
|
-
|
21
|
-
# All read operations should be intelligently directed to either the master
|
22
|
-
# or the slave, depending on where the read counter is and what it's
|
23
|
-
# maximum was configured at.
|
24
|
-
#
|
25
|
-
# Example:
|
26
|
-
#
|
27
|
-
# <tt>collection.find({ :name => "Al" })</tt>
|
28
|
-
proxy(:directed, (Collections::Operations::READ - [:find]))
|
19
|
+
proxy(:master, Collections::Operations::PROXIED)
|
29
20
|
|
30
21
|
# Determines where to send the next read query. If the slaves are not
|
31
22
|
# defined then send to master. If the read counter is under the configured
|
@@ -38,14 +29,9 @@ module Mongoid #:nodoc
|
|
38
29
|
# Return:
|
39
30
|
#
|
40
31
|
# Either a +Master+ or +Slaves+ collection.
|
41
|
-
def directed
|
42
|
-
|
43
|
-
|
44
|
-
master
|
45
|
-
else
|
46
|
-
@counter = 0
|
47
|
-
slaves
|
48
|
-
end
|
32
|
+
def directed(options = {})
|
33
|
+
enslave = options.delete(:enslave)
|
34
|
+
enslave ? master_or_slaves : master
|
49
35
|
end
|
50
36
|
|
51
37
|
# Find documents from the database given a selector and options.
|
@@ -59,7 +45,7 @@ module Mongoid #:nodoc
|
|
59
45
|
#
|
60
46
|
# <tt>collection.find({ :test => "value" })</tt>
|
61
47
|
def find(selector = {}, options = {})
|
62
|
-
cursor = Mongoid::Cursor.new(self, directed.find(selector, options))
|
48
|
+
cursor = Mongoid::Cursor.new(@klass, self, directed(options).find(selector, options))
|
63
49
|
if block_given?
|
64
50
|
yield cursor; cursor.close
|
65
51
|
else
|
@@ -67,27 +53,42 @@ module Mongoid #:nodoc
|
|
67
53
|
end
|
68
54
|
end
|
69
55
|
|
56
|
+
# Find the first document from the database given a selector and options.
|
57
|
+
#
|
58
|
+
# Options:
|
59
|
+
#
|
60
|
+
# selector: A +Hash+ selector that is the query.
|
61
|
+
# options: The options to pass to the db.
|
62
|
+
#
|
63
|
+
# Example:
|
64
|
+
#
|
65
|
+
# <tt>collection.find_one({ :test => "value" })</tt>
|
66
|
+
def find_one(selector = {}, options = {})
|
67
|
+
directed(options).find_one(selector, options)
|
68
|
+
end
|
69
|
+
|
70
70
|
# Initialize a new Mongoid::Collection, setting up the master, slave, and
|
71
71
|
# name attributes. Masters will be used for writes, slaves for reads.
|
72
72
|
#
|
73
73
|
# Example:
|
74
74
|
#
|
75
75
|
# <tt>Mongoid::Collection.new(masters, slaves, "test")</tt>
|
76
|
-
def initialize(name)
|
77
|
-
@
|
76
|
+
def initialize(klass, name)
|
77
|
+
@klass, @name = klass, name
|
78
78
|
end
|
79
79
|
|
80
|
-
#
|
81
|
-
# This is usually the slave databases, but in their absence the master will
|
82
|
-
# handle the task.
|
80
|
+
# Perform a map/reduce on the documents.
|
83
81
|
#
|
84
|
-
#
|
82
|
+
# Options:
|
85
83
|
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
84
|
+
# map: The map javascript funcdtion.
|
85
|
+
# reduce: The reduce javascript function.
|
86
|
+
def map_reduce(map, reduce, options = {})
|
87
|
+
directed(options).map_reduce(map, reduce, options)
|
89
88
|
end
|
90
89
|
|
90
|
+
alias :mapreduce :map_reduce
|
91
|
+
|
91
92
|
# Return the object responsible for writes to the database. This will
|
92
93
|
# always return a collection associated with the Master DB.
|
93
94
|
#
|
@@ -98,9 +99,20 @@ module Mongoid #:nodoc
|
|
98
99
|
@master ||= Collections::Master.new(Mongoid.master, @name)
|
99
100
|
end
|
100
101
|
|
102
|
+
# Return the object responsible for reading documents from the database.
|
103
|
+
# This is usually the slave databases, but in their absence the master will
|
104
|
+
# handle the task.
|
105
|
+
#
|
106
|
+
# Example:
|
107
|
+
#
|
108
|
+
# <tt>collection.reader</tt>
|
109
|
+
def slaves
|
110
|
+
@slaves ||= Collections::Slaves.new(Mongoid.slaves, @name)
|
111
|
+
end
|
112
|
+
|
101
113
|
protected
|
102
|
-
def
|
103
|
-
|
114
|
+
def master_or_slaves
|
115
|
+
slaves.empty? ? master : slaves
|
104
116
|
end
|
105
117
|
end
|
106
118
|
end
|
@@ -6,6 +6,7 @@ module Mongoid #:nodoc:
|
|
6
6
|
# Mongo:Collection. This is used in delegation.
|
7
7
|
READ = [
|
8
8
|
:[],
|
9
|
+
:db,
|
9
10
|
:count,
|
10
11
|
:distinct,
|
11
12
|
:find,
|
@@ -34,6 +35,7 @@ module Mongoid #:nodoc:
|
|
34
35
|
|
35
36
|
# Convenience constant for getting back all collection operations.
|
36
37
|
ALL = (READ + WRITE)
|
38
|
+
PROXIED = ALL - [ :find, :find_one, :map_reduce, :mapreduce ]
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
data/lib/mongoid/config.rb
CHANGED
@@ -5,7 +5,6 @@ module Mongoid #:nodoc
|
|
5
5
|
|
6
6
|
attr_accessor \
|
7
7
|
:allow_dynamic_fields,
|
8
|
-
:max_successive_reads,
|
9
8
|
:reconnect_time,
|
10
9
|
:parameterize_keys,
|
11
10
|
:persist_in_safe_mode,
|
@@ -14,7 +13,6 @@ module Mongoid #:nodoc
|
|
14
13
|
# Defaults the configuration options to true.
|
15
14
|
def initialize
|
16
15
|
@allow_dynamic_fields = true
|
17
|
-
@max_successive_reads = 10
|
18
16
|
@parameterize_keys = true
|
19
17
|
@persist_in_safe_mode = true
|
20
18
|
@raise_not_found_error = true
|
@@ -79,7 +79,7 @@ module Mongoid #:nodoc:
|
|
79
79
|
true
|
80
80
|
).collect do |docs|
|
81
81
|
docs["group"] = docs["group"].collect do |attrs|
|
82
|
-
Mongoid::Factory.build(attrs)
|
82
|
+
Mongoid::Factory.build(@klass, attrs)
|
83
83
|
end
|
84
84
|
docs
|
85
85
|
end
|
@@ -115,7 +115,7 @@ module Mongoid #:nodoc:
|
|
115
115
|
sorting = [[:_id, :asc]] unless sorting
|
116
116
|
opts[:sort] = sorting.collect { |option| [ option[0], option[1].invert ] }
|
117
117
|
attributes = @klass.collection.find_one(@selector, opts)
|
118
|
-
attributes ? Mongoid::Factory.build(attributes) : nil
|
118
|
+
attributes ? Mongoid::Factory.build(@klass, attributes) : nil
|
119
119
|
end
|
120
120
|
|
121
121
|
MAX_REDUCE = "function(obj, prev) { if (prev.max == 'start') { prev.max = obj.[field]; } " +
|
@@ -169,7 +169,7 @@ module Mongoid #:nodoc:
|
|
169
169
|
# The first document in the collection.
|
170
170
|
def one
|
171
171
|
attributes = @klass.collection.find_one(@selector, process_options)
|
172
|
-
attributes ? Mongoid::Factory.build(attributes) : nil
|
172
|
+
attributes ? Mongoid::Factory.build(@klass, attributes) : nil
|
173
173
|
end
|
174
174
|
|
175
175
|
alias :first :one
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -94,6 +94,20 @@ module Mongoid #:nodoc:
|
|
94
94
|
@context ||= determine_context
|
95
95
|
end
|
96
96
|
|
97
|
+
# Iterate over each +Document+ in the results. This can take an optional
|
98
|
+
# block to pass to each argument in the results.
|
99
|
+
#
|
100
|
+
# Example:
|
101
|
+
#
|
102
|
+
# <tt>criteria.each { |doc| p doc }</tt>
|
103
|
+
def each(&block)
|
104
|
+
return each_cached(&block) if cached?
|
105
|
+
if block_given?
|
106
|
+
execute.each { |doc| yield doc }
|
107
|
+
end
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
97
111
|
# Merges the supplied argument hash into a single criteria
|
98
112
|
#
|
99
113
|
# Options:
|
@@ -111,19 +125,6 @@ module Mongoid #:nodoc:
|
|
111
125
|
end
|
112
126
|
end
|
113
127
|
|
114
|
-
# Iterate over each +Document+ in the results. This can take an optional
|
115
|
-
# block to pass to each argument in the results.
|
116
|
-
#
|
117
|
-
# Example:
|
118
|
-
#
|
119
|
-
# <tt>criteria.each { |doc| p doc }</tt>
|
120
|
-
def each(&block)
|
121
|
-
if block_given?
|
122
|
-
execute.each { |doc| yield doc }
|
123
|
-
end
|
124
|
-
self
|
125
|
-
end
|
126
|
-
|
127
128
|
# Create the new +Criteria+ object. This will initialize the selector
|
128
129
|
# and options hashes, as well as the type of criteria.
|
129
130
|
#
|
@@ -198,10 +199,7 @@ module Mongoid #:nodoc:
|
|
198
199
|
# Example:
|
199
200
|
#
|
200
201
|
# <tt>Criteria.translate(Person, "4ab2bc4b8ad548971900005c")</tt>
|
201
|
-
#
|
202
202
|
# <tt>Criteria.translate(Person, :conditions => { :field => "value"}, :limit => 20)</tt>
|
203
|
-
#
|
204
|
-
# Returns a new +Criteria+ object.
|
205
203
|
def self.translate(*args)
|
206
204
|
klass = args[0]
|
207
205
|
params = args[1] || {}
|
@@ -220,10 +218,6 @@ module Mongoid #:nodoc:
|
|
220
218
|
# Example:
|
221
219
|
#
|
222
220
|
# <tt>criteria#determine_context</tt>
|
223
|
-
#
|
224
|
-
# Returns:
|
225
|
-
#
|
226
|
-
# A enumerable or mongo context.
|
227
221
|
def determine_context
|
228
222
|
if @klass.embedded
|
229
223
|
return Contexts::Enumerable.new(@selector, @options, @documents)
|
@@ -231,6 +225,20 @@ module Mongoid #:nodoc:
|
|
231
225
|
Contexts::Mongo.new(@selector, @options, @klass)
|
232
226
|
end
|
233
227
|
|
228
|
+
# Iterate over each +Document+ in the results and cache the collection.
|
229
|
+
def each_cached(&block)
|
230
|
+
@collection ||= execute
|
231
|
+
if block_given?
|
232
|
+
docs = []
|
233
|
+
@collection.each do |doc|
|
234
|
+
docs << doc
|
235
|
+
yield doc
|
236
|
+
end
|
237
|
+
@collection = docs
|
238
|
+
end
|
239
|
+
self
|
240
|
+
end
|
241
|
+
|
234
242
|
# Filters the unused options out of the options +Hash+. Currently this
|
235
243
|
# takes into account the "page" and "per_page" options that would be passed
|
236
244
|
# in if using will_paginate.
|
@@ -2,6 +2,38 @@
|
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Criterion #:nodoc:
|
4
4
|
module Optional
|
5
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
6
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
7
|
+
# times, however this is not advisable when working with large data sets
|
8
|
+
# as the entire results will get stored in memory.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# <tt>criteria.cache</tt>
|
13
|
+
def cache
|
14
|
+
@options.merge!(:cache => true); self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Will return true if the cache option has been set.
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
#
|
21
|
+
# <tt>criteria.cached?</tt>
|
22
|
+
def cached?
|
23
|
+
@cached ||= @options.delete(:cache)
|
24
|
+
@cached == true
|
25
|
+
end
|
26
|
+
|
27
|
+
# Flags the criteria to execute against a read-only slave in the pool
|
28
|
+
# instead of master.
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
#
|
32
|
+
# <tt>criteria.enslave</tt>
|
33
|
+
def enslave
|
34
|
+
@options.merge!(:enslave => true); self
|
35
|
+
end
|
36
|
+
|
5
37
|
# Adds a criterion to the +Criteria+ that specifies additional options
|
6
38
|
# to be passed to the Ruby driver, in the exact format for the driver.
|
7
39
|
#
|
data/lib/mongoid/cursor.rb
CHANGED
@@ -42,7 +42,7 @@ module Mongoid #:nodoc
|
|
42
42
|
# <tt>cursor.each { |doc| p doc.title }</tt>
|
43
43
|
def each
|
44
44
|
@cursor.each do |document|
|
45
|
-
yield Mongoid::Factory.build(document)
|
45
|
+
yield Mongoid::Factory.build(@klass, document)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -55,9 +55,9 @@ module Mongoid #:nodoc
|
|
55
55
|
#
|
56
56
|
# Example:
|
57
57
|
#
|
58
|
-
# <tt>Mongoid::Cursor.new(
|
59
|
-
def initialize(collection, cursor)
|
60
|
-
@collection, @cursor = collection, cursor
|
58
|
+
# <tt>Mongoid::Cursor.new(Person, cursor)</tt>
|
59
|
+
def initialize(klass, collection, cursor)
|
60
|
+
@klass, @collection, @cursor = klass, collection, cursor
|
61
61
|
end
|
62
62
|
|
63
63
|
# Return the next document in the cursor. Will instantiate a new Mongoid
|
@@ -67,7 +67,7 @@ module Mongoid #:nodoc
|
|
67
67
|
#
|
68
68
|
# <tt>cursor.next_document</tt>
|
69
69
|
def next_document
|
70
|
-
Mongoid::Factory.build(@cursor.next_document)
|
70
|
+
Mongoid::Factory.build(@klass, @cursor.next_document)
|
71
71
|
end
|
72
72
|
|
73
73
|
# Returns an array of all the documents in the cursor.
|
@@ -76,7 +76,7 @@ module Mongoid #:nodoc
|
|
76
76
|
#
|
77
77
|
# <tt>cursor.to_a</tt>
|
78
78
|
def to_a
|
79
|
-
@cursor.to_a.collect { |attrs| Mongoid::Factory.build(attrs) }
|
79
|
+
@cursor.to_a.collect { |attrs| Mongoid::Factory.build(@klass, attrs) }
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
data/lib/mongoid/document.rb
CHANGED
@@ -21,11 +21,16 @@ module Mongoid #:nodoc:
|
|
21
21
|
attr_accessor :association_name, :_parent
|
22
22
|
attr_reader :new_record
|
23
23
|
|
24
|
-
delegate :collection, :embedded, :primary_key, :to => "self.class"
|
24
|
+
delegate :collection, :db, :embedded, :primary_key, :to => "self.class"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
module ClassMethods
|
29
|
+
# Return the database associated with this class.
|
30
|
+
def db
|
31
|
+
collection.db
|
32
|
+
end
|
33
|
+
|
29
34
|
# Returns the collection associated with this +Document+. If the
|
30
35
|
# document is embedded, there will be no collection associated
|
31
36
|
# with it.
|
@@ -33,7 +38,7 @@ module Mongoid #:nodoc:
|
|
33
38
|
# Returns: <tt>Mongo::Collection</tt>
|
34
39
|
def collection
|
35
40
|
raise Errors::InvalidCollection.new(self) if embedded
|
36
|
-
self._collection ||= Mongoid::Collection.new(self.collection_name)
|
41
|
+
self._collection ||= Mongoid::Collection.new(self, self.collection_name)
|
37
42
|
add_indexes; self._collection
|
38
43
|
end
|
39
44
|
|
@@ -94,7 +99,7 @@ module Mongoid #:nodoc:
|
|
94
99
|
# <tt>Person.store_in :populdation</tt>
|
95
100
|
def store_in(name)
|
96
101
|
self.collection_name = name.to_s
|
97
|
-
self._collection = Mongoid::Collection.new(name.to_s)
|
102
|
+
self._collection = Mongoid::Collection.new(self, name.to_s)
|
98
103
|
end
|
99
104
|
|
100
105
|
# Returns all types to query for when using this class as the base.
|
@@ -125,8 +130,6 @@ module Mongoid #:nodoc:
|
|
125
130
|
# Example:
|
126
131
|
#
|
127
132
|
# <tt>name.assimilate(person, options)</tt>
|
128
|
-
#
|
129
|
-
# Returns: The child +Document+.
|
130
133
|
def assimilate(parent, options)
|
131
134
|
parentize(parent, options.name); notify; self
|
132
135
|
end
|
@@ -157,10 +160,6 @@ module Mongoid #:nodoc:
|
|
157
160
|
# Options:
|
158
161
|
#
|
159
162
|
# attrs: The attributes +Hash+ to set up the document with.
|
160
|
-
#
|
161
|
-
# Example:
|
162
|
-
#
|
163
|
-
# <tt>Person.new(:title => "Mr", :age => 30)</tt>
|
164
163
|
def initialize(attrs = nil)
|
165
164
|
@attributes = {}
|
166
165
|
process(attrs)
|
@@ -272,10 +271,6 @@ module Mongoid #:nodoc:
|
|
272
271
|
# child: The child +Document+ that sent the notification.
|
273
272
|
# clear: Will clear out the child's attributes if set to true.
|
274
273
|
#
|
275
|
-
# Example:
|
276
|
-
#
|
277
|
-
# <tt>person.notify_observers(self)</tt> will cause this method to execute.
|
278
|
-
#
|
279
274
|
# This will also cause the observing +Document+ to notify it's parent if
|
280
275
|
# there is any.
|
281
276
|
def update(child, clear = false)
|
data/lib/mongoid/factory.rb
CHANGED
@@ -9,9 +9,11 @@ module Mongoid #:nodoc:
|
|
9
9
|
#
|
10
10
|
# Options:
|
11
11
|
#
|
12
|
+
# klass: The class to instantiate from if _type is not present.
|
12
13
|
# attributes: The +Document+ attributes.
|
13
|
-
def self.build(
|
14
|
-
|
14
|
+
def self.build(klass, attrs)
|
15
|
+
type = attrs["_type"]
|
16
|
+
type ? type.constantize.instantiate(attrs) : klass.instantiate(attrs)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
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 = "1.2.
|
8
|
+
s.version = "1.2.4"
|
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-02-
|
12
|
+
s.date = %q{2010-02-09}
|
13
13
|
s.email = %q{durran@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.rdoc"
|
@@ -16,10 +16,6 @@ describe Mongoid::Criteria do
|
|
16
16
|
@person = Person.create(:title => "Sir", :age => 100, :aliases => ["D", "Durran"], :ssn => "666666666")
|
17
17
|
end
|
18
18
|
|
19
|
-
after do
|
20
|
-
Person.delete_all
|
21
|
-
end
|
22
|
-
|
23
19
|
context "when passed id" do
|
24
20
|
|
25
21
|
it "it properly excludes ids" do
|
@@ -46,10 +42,6 @@ describe Mongoid::Criteria do
|
|
46
42
|
@person = Person.create(:title => "Sir", :age => 100, :aliases => ["D", "Durran"], :ssn => "666666666")
|
47
43
|
end
|
48
44
|
|
49
|
-
after do
|
50
|
-
Person.delete_all
|
51
|
-
end
|
52
|
-
|
53
45
|
it "executes the query again" do
|
54
46
|
criteria = Person.all
|
55
47
|
criteria.size.should == 1
|
@@ -66,10 +58,6 @@ describe Mongoid::Criteria do
|
|
66
58
|
end
|
67
59
|
end
|
68
60
|
|
69
|
-
after do
|
70
|
-
Person.delete_all
|
71
|
-
end
|
72
|
-
|
73
61
|
it "provides max for the field provided" do
|
74
62
|
Person.max(:age).should == 90.0
|
75
63
|
end
|
@@ -84,10 +72,6 @@ describe Mongoid::Criteria do
|
|
84
72
|
end
|
85
73
|
end
|
86
74
|
|
87
|
-
after do
|
88
|
-
Person.delete_all
|
89
|
-
end
|
90
|
-
|
91
75
|
it "provides min for the field provided" do
|
92
76
|
Person.min(:age).should == 10.0
|
93
77
|
end
|
@@ -102,10 +86,6 @@ describe Mongoid::Criteria do
|
|
102
86
|
end
|
103
87
|
end
|
104
88
|
|
105
|
-
after do
|
106
|
-
Person.delete_all
|
107
|
-
end
|
108
|
-
|
109
89
|
it "provides sum for the field provided" do
|
110
90
|
Person.where(:age.gt => 3).sum(:age).should == 50.0
|
111
91
|
end
|
@@ -118,10 +98,6 @@ describe Mongoid::Criteria do
|
|
118
98
|
@person = Person.create(:title => "Sir", :age => 33, :aliases => ["D", "Durran"])
|
119
99
|
end
|
120
100
|
|
121
|
-
after do
|
122
|
-
Person.delete_all
|
123
|
-
end
|
124
|
-
|
125
101
|
context "with complex criterion" do
|
126
102
|
|
127
103
|
context "#all" do
|
@@ -208,4 +184,20 @@ describe Mongoid::Criteria do
|
|
208
184
|
|
209
185
|
end
|
210
186
|
|
187
|
+
context "when caching" do
|
188
|
+
|
189
|
+
before do
|
190
|
+
10.times do |n|
|
191
|
+
Person.create(:title => "Sir", :age => (n * 10), :aliases => ["D", "Durran"], :ssn => "#{n}")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
it "iterates over the cursor only once" do
|
196
|
+
criteria = Person.where(:title => "Sir").cache
|
197
|
+
criteria.collect.size.should == 10
|
198
|
+
# Do it again!
|
199
|
+
criteria.collect.size.should == 10
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
211
203
|
end
|
@@ -11,7 +11,7 @@ describe Mongoid::Collection do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
let(:collection) do
|
14
|
-
Mongoid::Collection.new("people")
|
14
|
+
Mongoid::Collection.new(Person, "people")
|
15
15
|
end
|
16
16
|
|
17
17
|
before do
|
@@ -40,73 +40,101 @@ describe Mongoid::Collection do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe "#
|
43
|
+
describe "#find" do
|
44
|
+
|
45
|
+
before do
|
46
|
+
@cursor = stub.quacks_like(Mongoid::Cursor.allocate)
|
47
|
+
Mongoid::Cursor.expects(:new).with(Person, collection, @mongo_cursor).returns(@cursor)
|
48
|
+
end
|
44
49
|
|
45
|
-
context "when
|
50
|
+
context "when no block supplied" do
|
46
51
|
|
47
52
|
before do
|
48
|
-
|
53
|
+
master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
|
49
54
|
end
|
50
55
|
|
51
|
-
it "
|
52
|
-
collection.
|
56
|
+
it "finds return a cursor" do
|
57
|
+
collection.find({ :test => "value"}).should == @cursor
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when a block is supplied" do
|
63
|
+
|
64
|
+
before do
|
65
|
+
master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
|
53
66
|
end
|
54
67
|
|
55
|
-
it "
|
56
|
-
|
57
|
-
collection.
|
68
|
+
it "yields to the cursor and closes it" do
|
69
|
+
@cursor.expects(:close).returns(true)
|
70
|
+
collection.find({ :test => "value" }) do |cur|
|
71
|
+
cur.should == @cursor
|
72
|
+
end
|
58
73
|
end
|
59
74
|
end
|
60
75
|
|
61
|
-
context "when
|
76
|
+
context "when an enslave option exists" do
|
62
77
|
|
63
78
|
before do
|
79
|
+
@options = { :enslave => true }
|
64
80
|
slaves.expects(:empty?).returns(false)
|
65
|
-
|
81
|
+
slaves.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
|
66
82
|
end
|
67
83
|
|
68
|
-
it "
|
69
|
-
collection.
|
84
|
+
it "sends the query to the slave pool" do
|
85
|
+
collection.find({ :test => "value"}, @options).should == @cursor
|
70
86
|
end
|
71
87
|
|
72
|
-
it "
|
73
|
-
collection.
|
74
|
-
|
88
|
+
it "deletes the enslave option" do
|
89
|
+
collection.find({ :test => "value"}, @options)
|
90
|
+
@options[:enslave].should be_nil
|
75
91
|
end
|
76
92
|
end
|
77
93
|
|
78
|
-
context "when
|
94
|
+
context "when an enslave option does not exist" do
|
79
95
|
|
80
96
|
before do
|
81
|
-
|
82
|
-
slaves.expects(:empty?).returns(true)
|
97
|
+
master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
|
83
98
|
end
|
84
99
|
|
85
|
-
it "
|
86
|
-
collection.
|
100
|
+
it "sends the query to the master" do
|
101
|
+
collection.find({ :test => "value"}).should == @cursor
|
87
102
|
end
|
88
103
|
end
|
89
104
|
end
|
90
105
|
|
91
|
-
describe "#
|
106
|
+
describe "#find_one" do
|
92
107
|
|
93
108
|
before do
|
94
|
-
@
|
95
|
-
master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
|
96
|
-
Mongoid::Cursor.expects(:new).with(collection, @mongo_cursor).returns(@cursor)
|
109
|
+
@person = stub
|
97
110
|
end
|
98
111
|
|
99
|
-
|
100
|
-
|
112
|
+
context "when an enslave option exists" do
|
113
|
+
|
114
|
+
before do
|
115
|
+
@options = { :enslave => true }
|
116
|
+
slaves.expects(:empty?).returns(false)
|
117
|
+
slaves.expects(:find_one).with({ :test => "value" }, {}).returns(@person)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "sends the query to the slave pool" do
|
121
|
+
collection.find_one({ :test => "value"}, @options).should == @person
|
122
|
+
end
|
123
|
+
|
124
|
+
it "deletes the enslave option" do
|
125
|
+
collection.find_one({ :test => "value"}, @options)
|
126
|
+
@options[:enslave].should be_nil
|
127
|
+
end
|
101
128
|
end
|
102
129
|
|
103
|
-
context "when
|
130
|
+
context "when an enslave option does not exist" do
|
104
131
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
132
|
+
before do
|
133
|
+
master.expects(:find_one).with({ :test => "value" }, {}).returns(@person)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "sends the query to the master" do
|
137
|
+
collection.find_one({ :test => "value"}).should == @person
|
110
138
|
end
|
111
139
|
end
|
112
140
|
end
|
@@ -337,7 +337,9 @@ describe Mongoid::Contexts::Mongo do
|
|
337
337
|
Person.expects(:collection).returns(@collection)
|
338
338
|
@criteria = Person.where(:_id => "1").skip(60).limit(20)
|
339
339
|
@context = Mongoid::Contexts::Mongo.new(@criteria.selector, @criteria.options, Person)
|
340
|
-
@collection.expects(:find).with(
|
340
|
+
@collection.expects(:find).with(
|
341
|
+
{:_type => { "$in" => ["Doctor", "Person"] }, :_id => "1"}, :skip => 60, :limit => 20
|
342
|
+
).returns([])
|
341
343
|
@results = @context.paginate
|
342
344
|
end
|
343
345
|
|
@@ -316,6 +316,30 @@ describe Mongoid::Criteria do
|
|
316
316
|
|
317
317
|
end
|
318
318
|
|
319
|
+
context "when caching" do
|
320
|
+
|
321
|
+
before do
|
322
|
+
Person.expects(:collection).returns(@collection)
|
323
|
+
@collection.expects(:find).with({ :_type => { "$in" => ["Doctor", "Person"] }, :title => "Sir" }, {}).returns(@cursor)
|
324
|
+
@cursor.expects(:each).yields(@person)
|
325
|
+
@criteria.cache
|
326
|
+
@criteria.each do |doc|
|
327
|
+
doc.should == @person
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
it "caches the results of the cursor iteration" do
|
332
|
+
@criteria.each do |doc|
|
333
|
+
doc.should == @person
|
334
|
+
end
|
335
|
+
# Do it again for sanity's sake.
|
336
|
+
@criteria.each do |doc|
|
337
|
+
doc.should == @person
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
end
|
342
|
+
|
319
343
|
end
|
320
344
|
|
321
345
|
describe "#first" do
|
@@ -7,6 +7,61 @@ describe Mongoid::Criterion::Optional do
|
|
7
7
|
@canvas_criteria = Mongoid::Criteria.new(Canvas)
|
8
8
|
end
|
9
9
|
|
10
|
+
describe "#cache" do
|
11
|
+
|
12
|
+
it "sets the cache option on the criteria" do
|
13
|
+
@criteria.cache
|
14
|
+
@criteria.options[:cache].should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns self" do
|
18
|
+
@criteria.cache.should == @criteria
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#cached?" do
|
23
|
+
|
24
|
+
context "when the criteria has a cache option" do
|
25
|
+
|
26
|
+
before do
|
27
|
+
@criteria.cache
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true" do
|
31
|
+
@criteria.cached?.should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "removes cache from the options" do
|
35
|
+
@criteria.cached?
|
36
|
+
@criteria.options[:cache].should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sets the cache instance variable" do
|
40
|
+
@criteria.cached?
|
41
|
+
@criteria.instance_variable_get(:@cached).should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when the criteria has no cache option" do
|
46
|
+
|
47
|
+
it "returns false" do
|
48
|
+
@criteria.cached?.should be_false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#enslave" do
|
54
|
+
|
55
|
+
it "sets the enslaved option on the criteria" do
|
56
|
+
@criteria.enslave
|
57
|
+
@criteria.options[:enslave].should be_true
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns self" do
|
61
|
+
@criteria.enslave.should == @criteria
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
10
65
|
describe "#extras" do
|
11
66
|
|
12
67
|
context "filtering" do
|
@@ -6,8 +6,8 @@ describe Mongoid::Document do
|
|
6
6
|
@database = mock
|
7
7
|
@collection = stub(:name => "people")
|
8
8
|
@canvas_collection = stub(:name => "canvases")
|
9
|
-
Mongoid::Collection.stubs(:new).with("people").returns(@collection)
|
10
|
-
Mongoid::Collection.stubs(:new).with("canvases").returns(@canvas_collection)
|
9
|
+
Mongoid::Collection.stubs(:new).with(Person, "people").returns(@collection)
|
10
|
+
Mongoid::Collection.stubs(:new).with(Canvas, "canvases").returns(@canvas_collection)
|
11
11
|
@collection.stubs(:create_index).with(:_type, false)
|
12
12
|
@canvas_collection.stubs(:create_index).with(:_type, false)
|
13
13
|
end
|
@@ -99,6 +99,18 @@ describe Mongoid::Document do
|
|
99
99
|
|
100
100
|
end
|
101
101
|
|
102
|
+
describe ".db" do
|
103
|
+
|
104
|
+
before do
|
105
|
+
@db = stub
|
106
|
+
@collection.expects(:db).returns(@db)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns the database from the collection" do
|
110
|
+
Person.db.should == @db
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
102
114
|
describe "#clone" do
|
103
115
|
|
104
116
|
before do
|
@@ -552,7 +564,7 @@ describe Mongoid::Document do
|
|
552
564
|
context "on a parent class" do
|
553
565
|
|
554
566
|
it "sets the collection name and collection for the document" do
|
555
|
-
Mongoid::Collection.expects(:new).with("population").returns(@collection)
|
567
|
+
Mongoid::Collection.expects(:new).with(Patient, "population").returns(@collection)
|
556
568
|
Patient.store_in :population
|
557
569
|
Patient.collection_name.should == "population"
|
558
570
|
end
|
@@ -562,11 +574,12 @@ describe Mongoid::Document do
|
|
562
574
|
context "on a subclass" do
|
563
575
|
|
564
576
|
after do
|
577
|
+
Mongoid::Collection.expects(:new).with(Firefox, "canvases")
|
565
578
|
Firefox.store_in :canvases
|
566
579
|
end
|
567
580
|
|
568
581
|
it "changes the collection name for the entire hierarchy" do
|
569
|
-
Mongoid::Collection.expects(:new).with("browsers").returns(@collection)
|
582
|
+
Mongoid::Collection.expects(:new).with(Firefox, "browsers").returns(@collection)
|
570
583
|
Firefox.store_in :browsers
|
571
584
|
Canvas.collection_name.should == "browsers"
|
572
585
|
end
|
@@ -4,13 +4,28 @@ describe Mongoid::Factory do
|
|
4
4
|
|
5
5
|
describe ".build" do
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
context "when the _type attribute is present" do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@attributes = { "_type" => "Person", "title" => "Sir" }
|
11
|
+
end
|
12
|
+
|
13
|
+
it "instantiates based on the type" do
|
14
|
+
person = Mongoid::Factory.build(Person, @attributes)
|
15
|
+
person.title.should == "Sir"
|
16
|
+
end
|
9
17
|
end
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
19
|
+
context "when _type is not preset" do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@attributes = { "title" => "Sir" }
|
23
|
+
end
|
24
|
+
|
25
|
+
it "instantiates based on the type" do
|
26
|
+
person = Mongoid::Factory.build(Person, @attributes)
|
27
|
+
person.title.should == "Sir"
|
28
|
+
end
|
14
29
|
end
|
15
30
|
end
|
16
31
|
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: 1.2.
|
4
|
+
version: 1.2.4
|
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-02-
|
12
|
+
date: 2010-02-09 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|