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 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