mongoid 1.2.3 → 1.2.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.3
1
+ 1.2.4
@@ -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::WRITE)
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
- if under_max_counter? || slaves.empty?
43
- @counter = @counter + 1
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
- @name, @counter = name, 0
76
+ def initialize(klass, name)
77
+ @klass, @name = klass, name
78
78
  end
79
79
 
80
- # Return the object responsible for reading documents from the database.
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
- # Example:
82
+ # Options:
85
83
  #
86
- # <tt>collection.reader</tt>
87
- def slaves
88
- @slaves ||= Collections::Slaves.new(Mongoid.slaves, @name)
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 under_max_counter?
103
- @counter < Mongoid.max_successive_reads
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
@@ -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
@@ -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
  #
@@ -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(collection, cursor)</tt>
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
@@ -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)
@@ -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(attributes)
14
- attributes["_type"].constantize.instantiate(attributes)
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.3"
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-08}
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
@@ -6,6 +6,13 @@ describe Mongoid::Document do
6
6
  Person.delete_all
7
7
  end
8
8
 
9
+ describe "#db" do
10
+
11
+ it "returns the mongo database" do
12
+ Person.db.should == Mongoid.master
13
+ end
14
+ end
15
+
9
16
  context "when document contains a hash field" do
10
17
 
11
18
  before do
@@ -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 "#directed" do
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 the counter is less than the maximum" do
50
+ context "when no block supplied" do
46
51
 
47
52
  before do
48
- collection.instance_variable_set(:@counter, 0)
53
+ master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
49
54
  end
50
55
 
51
- it "delegates to the master" do
52
- collection.directed.should == master
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 "increments the counter" do
56
- collection.directed
57
- collection.counter.should == 1
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 the counter is at the max" do
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
- collection.instance_variable_set(:@counter, 10)
81
+ slaves.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
66
82
  end
67
83
 
68
- it "delegates to the slave" do
69
- collection.directed.should == slaves
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 "resets the counter" do
73
- collection.directed
74
- collection.counter.should == 0
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 the slave does not exist" do
94
+ context "when an enslave option does not exist" do
79
95
 
80
96
  before do
81
- collection.instance_variable_set(:@counter, 10)
82
- slaves.expects(:empty?).returns(true)
97
+ master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
83
98
  end
84
99
 
85
- it "delegates to the master" do
86
- collection.directed.should == master
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 "#find" do
106
+ describe "#find_one" do
92
107
 
93
108
  before do
94
- @cursor = stub.quacks_like(Mongoid::Cursor.allocate)
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
- it "finds are returns a cursor" do
100
- collection.find({ :test => "value"}).should == @cursor
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 a block is supplied" do
130
+ context "when an enslave option does not exist" do
104
131
 
105
- it "yields to the cursor and closes it" do
106
- @cursor.expects(:close).returns(true)
107
- collection.find({ :test => "value" }) do |cur|
108
- cur.should == @cursor
109
- end
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({:_type => { "$in" => ["Doctor", "Person"] }, :_id => "1"}, :skip => 60, :limit => 20).returns([])
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
@@ -11,7 +11,7 @@ describe Mongoid::Cursor do
11
11
  end
12
12
 
13
13
  let(:cursor) do
14
- Mongoid::Cursor.new(collection, proxy)
14
+ Mongoid::Cursor.new(Person, collection, proxy)
15
15
  end
16
16
 
17
17
  (Mongoid::Cursor::OPERATIONS - [ :timeout ]).each do |name|
@@ -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
- before do
8
- @attributes = { "_type" => "Person", "title" => "Sir" }
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
- it "instantiates based on the type" do
12
- person = Mongoid::Factory.build(@attributes)
13
- person.title.should == "Sir"
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.3
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-08 00:00:00 -05:00
12
+ date: 2010-02-09 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency