mongoid 2.0.0.alpha → 2.0.0.beta.5

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.
Files changed (216) hide show
  1. data/lib/mongoid.rb +11 -5
  2. data/lib/mongoid/associations.rb +112 -107
  3. data/lib/mongoid/associations/belongs_to_related.rb +2 -3
  4. data/lib/mongoid/associations/embedded_in.rb +12 -4
  5. data/lib/mongoid/associations/{embed_many.rb → embeds_many.rb} +101 -32
  6. data/lib/mongoid/associations/{embed_one.rb → embeds_one.rb} +10 -10
  7. data/lib/mongoid/associations/has_many_related.rb +51 -5
  8. data/lib/mongoid/associations/has_one_related.rb +9 -5
  9. data/lib/mongoid/associations/meta_data.rb +2 -1
  10. data/lib/mongoid/associations/options.rb +15 -6
  11. data/lib/mongoid/associations/proxy.rb +14 -21
  12. data/lib/mongoid/attributes.rb +34 -13
  13. data/lib/mongoid/callbacks.rb +1 -2
  14. data/lib/mongoid/collection.rb +4 -3
  15. data/lib/mongoid/collections.rb +41 -0
  16. data/lib/mongoid/collections/master.rb +3 -2
  17. data/lib/mongoid/collections/slaves.rb +3 -2
  18. data/lib/mongoid/components.rb +4 -1
  19. data/lib/mongoid/config.rb +163 -13
  20. data/lib/mongoid/contexts.rb +1 -2
  21. data/lib/mongoid/contexts/enumerable.rb +1 -1
  22. data/lib/mongoid/contexts/mongo.rb +1 -1
  23. data/lib/mongoid/contexts/paging.rb +10 -2
  24. data/lib/mongoid/criteria.rb +13 -22
  25. data/lib/mongoid/criterion/exclusion.rb +3 -3
  26. data/lib/mongoid/criterion/inclusion.rb +17 -0
  27. data/lib/mongoid/criterion/optional.rb +1 -1
  28. data/lib/mongoid/dirty.rb +253 -0
  29. data/lib/mongoid/document.rb +40 -85
  30. data/lib/mongoid/errors.rb +48 -1
  31. data/lib/mongoid/extensions.rb +11 -9
  32. data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
  33. data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
  34. data/lib/mongoid/extensions/date/conversions.rb +13 -4
  35. data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
  36. data/lib/mongoid/extensions/float/conversions.rb +5 -1
  37. data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
  38. data/lib/mongoid/extensions/hash/conversions.rb +34 -4
  39. data/lib/mongoid/extensions/integer/conversions.rb +5 -1
  40. data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
  41. data/lib/mongoid/extensions/object/conversions.rb +3 -3
  42. data/lib/mongoid/extensions/string/conversions.rb +1 -1
  43. data/lib/mongoid/extensions/symbol/inflections.rb +5 -2
  44. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  45. data/lib/mongoid/factory.rb +2 -1
  46. data/lib/mongoid/field.rb +15 -2
  47. data/lib/mongoid/fields.rb +1 -1
  48. data/lib/mongoid/identity.rb +3 -3
  49. data/lib/mongoid/indexes.rb +3 -3
  50. data/lib/mongoid/matchers.rb +1 -2
  51. data/lib/mongoid/memoization.rb +8 -2
  52. data/lib/mongoid/named_scope.rb +0 -5
  53. data/lib/mongoid/observable.rb +1 -1
  54. data/lib/mongoid/paths.rb +30 -22
  55. data/lib/mongoid/persistence.rb +218 -0
  56. data/lib/mongoid/persistence/command.rb +39 -0
  57. data/lib/mongoid/persistence/insert.rb +47 -0
  58. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  59. data/lib/mongoid/persistence/remove.rb +39 -0
  60. data/lib/mongoid/persistence/remove_all.rb +37 -0
  61. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  62. data/lib/mongoid/persistence/update.rb +63 -0
  63. data/lib/mongoid/railtie.rb +53 -0
  64. data/lib/mongoid/railties/database.rake +37 -0
  65. data/lib/mongoid/timestamps.rb +2 -2
  66. data/lib/mongoid/validations.rb +2 -2
  67. data/lib/mongoid/validations/associated.rb +2 -2
  68. data/lib/mongoid/validations/uniqueness.rb +13 -2
  69. data/lib/mongoid/version.rb +4 -0
  70. data/lib/mongoid/versioning.rb +3 -2
  71. data/lib/rails/generators/mongoid/config/config_generator.rb +41 -0
  72. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
  73. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  74. data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
  75. data/lib/rails/generators/mongoid_generator.rb +61 -0
  76. metadata +76 -301
  77. data/.gitignore +0 -6
  78. data/.watchr +0 -29
  79. data/Rakefile +0 -52
  80. data/VERSION +0 -1
  81. data/caliper.yml +0 -4
  82. data/lib/mongoid/collections/mimic.rb +0 -46
  83. data/lib/mongoid/commands.rb +0 -161
  84. data/lib/mongoid/commands/create.rb +0 -19
  85. data/lib/mongoid/commands/delete.rb +0 -16
  86. data/lib/mongoid/commands/delete_all.rb +0 -23
  87. data/lib/mongoid/commands/deletion.rb +0 -18
  88. data/lib/mongoid/commands/destroy.rb +0 -17
  89. data/lib/mongoid/commands/destroy_all.rb +0 -23
  90. data/lib/mongoid/commands/save.rb +0 -29
  91. data/lib/mongoid/extensions/time/conversions.rb +0 -18
  92. data/mongoid.gemspec +0 -408
  93. data/perf/benchmark.rb +0 -77
  94. data/spec/integration/mongoid/associations_spec.rb +0 -340
  95. data/spec/integration/mongoid/attributes_spec.rb +0 -22
  96. data/spec/integration/mongoid/commands_spec.rb +0 -227
  97. data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
  98. data/spec/integration/mongoid/criteria_spec.rb +0 -272
  99. data/spec/integration/mongoid/document_spec.rb +0 -650
  100. data/spec/integration/mongoid/extensions_spec.rb +0 -22
  101. data/spec/integration/mongoid/finders_spec.rb +0 -119
  102. data/spec/integration/mongoid/inheritance_spec.rb +0 -137
  103. data/spec/integration/mongoid/named_scope_spec.rb +0 -46
  104. data/spec/models/address.rb +0 -39
  105. data/spec/models/animal.rb +0 -6
  106. data/spec/models/callbacks.rb +0 -18
  107. data/spec/models/comment.rb +0 -8
  108. data/spec/models/country_code.rb +0 -6
  109. data/spec/models/employer.rb +0 -5
  110. data/spec/models/game.rb +0 -7
  111. data/spec/models/inheritance.rb +0 -56
  112. data/spec/models/location.rb +0 -5
  113. data/spec/models/mixed_drink.rb +0 -4
  114. data/spec/models/name.rb +0 -13
  115. data/spec/models/namespacing.rb +0 -11
  116. data/spec/models/patient.rb +0 -4
  117. data/spec/models/person.rb +0 -99
  118. data/spec/models/pet.rb +0 -7
  119. data/spec/models/pet_owner.rb +0 -6
  120. data/spec/models/phone.rb +0 -7
  121. data/spec/models/post.rb +0 -15
  122. data/spec/models/translation.rb +0 -5
  123. data/spec/models/vet_visit.rb +0 -5
  124. data/spec/spec.opts +0 -3
  125. data/spec/spec_helper.rb +0 -31
  126. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
  127. data/spec/unit/mongoid/associations/embed_many_spec.rb +0 -516
  128. data/spec/unit/mongoid/associations/embed_one_spec.rb +0 -282
  129. data/spec/unit/mongoid/associations/embedded_in_spec.rb +0 -193
  130. data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -418
  131. data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
  132. data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
  133. data/spec/unit/mongoid/associations/options_spec.rb +0 -192
  134. data/spec/unit/mongoid/associations_spec.rb +0 -595
  135. data/spec/unit/mongoid/attributes_spec.rb +0 -507
  136. data/spec/unit/mongoid/callbacks_spec.rb +0 -55
  137. data/spec/unit/mongoid/collection_spec.rb +0 -187
  138. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
  139. data/spec/unit/mongoid/collections/master_spec.rb +0 -41
  140. data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
  141. data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
  142. data/spec/unit/mongoid/commands/create_spec.rb +0 -31
  143. data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
  144. data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
  145. data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -21
  146. data/spec/unit/mongoid/commands/destroy_spec.rb +0 -51
  147. data/spec/unit/mongoid/commands/save_spec.rb +0 -107
  148. data/spec/unit/mongoid/commands_spec.rb +0 -270
  149. data/spec/unit/mongoid/config_spec.rb +0 -172
  150. data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
  151. data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
  152. data/spec/unit/mongoid/contexts_spec.rb +0 -25
  153. data/spec/unit/mongoid/criteria_spec.rb +0 -824
  154. data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
  155. data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
  156. data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
  157. data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
  158. data/spec/unit/mongoid/cursor_spec.rb +0 -74
  159. data/spec/unit/mongoid/deprecation_spec.rb +0 -24
  160. data/spec/unit/mongoid/document_spec.rb +0 -818
  161. data/spec/unit/mongoid/errors_spec.rb +0 -103
  162. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
  163. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
  164. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
  165. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
  166. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
  167. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
  168. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
  169. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
  170. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -67
  171. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
  172. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
  173. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
  174. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
  175. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
  176. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
  177. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
  178. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
  179. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
  180. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
  181. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
  182. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
  183. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
  184. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
  185. data/spec/unit/mongoid/extras_spec.rb +0 -102
  186. data/spec/unit/mongoid/factory_spec.rb +0 -31
  187. data/spec/unit/mongoid/field_spec.rb +0 -143
  188. data/spec/unit/mongoid/fields_spec.rb +0 -181
  189. data/spec/unit/mongoid/finders_spec.rb +0 -404
  190. data/spec/unit/mongoid/identity_spec.rb +0 -109
  191. data/spec/unit/mongoid/indexes_spec.rb +0 -93
  192. data/spec/unit/mongoid/javascript_spec.rb +0 -48
  193. data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
  194. data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
  195. data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
  196. data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
  197. data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
  198. data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
  199. data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
  200. data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
  201. data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
  202. data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
  203. data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
  204. data/spec/unit/mongoid/matchers_spec.rb +0 -329
  205. data/spec/unit/mongoid/memoization_spec.rb +0 -75
  206. data/spec/unit/mongoid/named_scope_spec.rb +0 -123
  207. data/spec/unit/mongoid/observable_spec.rb +0 -46
  208. data/spec/unit/mongoid/paths_spec.rb +0 -124
  209. data/spec/unit/mongoid/scope_spec.rb +0 -240
  210. data/spec/unit/mongoid/state_spec.rb +0 -83
  211. data/spec/unit/mongoid/timestamps_spec.rb +0 -25
  212. data/spec/unit/mongoid/validations/associated_spec.rb +0 -103
  213. data/spec/unit/mongoid/validations/uniqueness_spec.rb +0 -47
  214. data/spec/unit/mongoid/validations_spec.rb +0 -190
  215. data/spec/unit/mongoid/versioning_spec.rb +0 -41
  216. data/spec/unit/mongoid_spec.rb +0 -46
@@ -1,30 +1,23 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc
3
3
  module Associations #:nodoc
4
- module Proxy #:nodoc
5
- def self.included(base)
6
- base.class_eval do
7
- instance_methods.each do |method|
8
- undef_method(method) unless method =~ /(^__|^nil\?$|^send$|^object_id$|^extend$)/
9
- end
10
- include InstanceMethods
11
- end
4
+ class Proxy #:nodoc
5
+ instance_methods.each do |method|
6
+ undef_method(method) unless method =~ /(^__|^nil\?$|^send$|^object_id$|^extend$)/
12
7
  end
13
- module InstanceMethods #:nodoc:
14
- attr_reader \
15
- :options,
16
- :target
8
+ attr_reader \
9
+ :options,
10
+ :target
17
11
 
18
- # Default behavior of method missing should be to delegate all calls
19
- # to the target of the proxy. This can be overridden in special cases.
20
- def method_missing(name, *args, &block)
21
- @target.send(name, *args, &block)
22
- end
12
+ # Default behavior of method missing should be to delegate all calls
13
+ # to the target of the proxy. This can be overridden in special cases.
14
+ def method_missing(name, *args, &block)
15
+ @target.send(name, *args, &block)
16
+ end
23
17
 
24
- # If anonymous extensions are added this will take care of them.
25
- def extends(options)
26
- extend Module.new(&options.extension) if options.extension?
27
- end
18
+ # If anonymous extensions are added this will take care of them.
19
+ def extends(options)
20
+ extend Module.new(&options.extension) if options.extension?
28
21
  end
29
22
  end
30
23
  end
@@ -41,6 +41,7 @@ module Mongoid #:nodoc:
41
41
  send("#{key}=", value)
42
42
  end
43
43
  end
44
+ setup_modifications
44
45
  end
45
46
 
46
47
  # Read a value from the +Document+ attributes. If the value does not exist
@@ -55,7 +56,7 @@ module Mongoid #:nodoc:
55
56
  # <tt>person.read_attribute(:title)</tt>
56
57
  def read_attribute(name)
57
58
  access = name.to_s
58
- fields[access].get(@attributes[access])
59
+ accessed(access, fields[access].get(@attributes[access]))
59
60
  end
60
61
 
61
62
  # Remove a value from the +Document+ attributes. If the value does not exist
@@ -69,7 +70,8 @@ module Mongoid #:nodoc:
69
70
  #
70
71
  # <tt>person.remove_attribute(:title)</tt>
71
72
  def remove_attribute(name)
72
- @attributes.delete(name.to_s)
73
+ access = name.to_s
74
+ modify(access, @attributes.delete(name.to_s), nil)
73
75
  end
74
76
 
75
77
  # Returns the object type. This corresponds to the name of the class that
@@ -101,8 +103,8 @@ module Mongoid #:nodoc:
101
103
  # there is any.
102
104
  def write_attribute(name, value)
103
105
  access = name.to_s
104
- @attributes[access] = fields[access].set(value)
105
- notify unless id.blank?
106
+ modify(access, @attributes[access], fields[access].set(value))
107
+ notify if !id.blank? && new_record?
106
108
  end
107
109
 
108
110
  # Writes the supplied attributes +Hash+ to the +Document+. This will only
@@ -121,12 +123,23 @@ module Mongoid #:nodoc:
121
123
  # there is any.
122
124
  def write_attributes(attrs = nil)
123
125
  process(attrs || {})
124
- identify if id.blank?
125
- notify
126
+ identified = !id.blank?
127
+ if new_record? && !identified
128
+ identify; notify
129
+ end
126
130
  end
127
131
  alias :attributes= :write_attributes
128
132
 
129
133
  protected
134
+ # apply default values to attributes - calling procs as required
135
+ def default_attributes
136
+ default_values = defaults
137
+ default_values.each_pair do |key, val|
138
+ default_values[key] = val.call if val.respond_to?(:call)
139
+ end
140
+ default_values || {}
141
+ end
142
+
130
143
  # Return true if dynamic field setting is enabled.
131
144
  def set_allowed?(key)
132
145
  Mongoid.allow_dynamic_fields && !respond_to?("#{key}=")
@@ -143,10 +156,17 @@ module Mongoid #:nodoc:
143
156
  end
144
157
  end
145
158
 
159
+ # Used when supplying a :limit as an option to accepts_nested_attributes_for
160
+ def limit(attributes, name, options)
161
+ raise Mongoid::Errors::TooManyNestedAttributeRecords.new(name, options[:limit]) if options[:limit] && attributes.size > options[:limit]
162
+ end
163
+
146
164
  # Return true if writing to the given field is allowed
147
165
  def write_allowed?(key)
148
- return true unless fields[key.to_s]
149
- fields[key.to_s].accessible?
166
+ name = key.to_s
167
+ existing = fields[name]
168
+ return true unless existing
169
+ existing.accessible?
150
170
  end
151
171
  end
152
172
 
@@ -158,8 +178,8 @@ module Mongoid #:nodoc:
158
178
  #
159
179
  # class Person
160
180
  # include Mongoid::Document
161
- # embed_one :name
162
- # embed_many :addresses
181
+ # embeds_one :name
182
+ # embeds_many :addresses
163
183
  #
164
184
  # accepts_nested_attributes_for :name, :addresses
165
185
  # end
@@ -169,12 +189,13 @@ module Mongoid #:nodoc:
169
189
  associations.each do |name|
170
190
  define_method("#{name}_attributes=") do |attrs|
171
191
  reject(attrs, options)
192
+ limit(attrs, name, options)
172
193
  association = send(name)
173
194
  if association
174
- update(association, true)
175
- association.nested_build(attrs)
195
+ # observe(association, true)
196
+ association.nested_build(attrs, options)
176
197
  else
177
- send("build_#{name}", attrs)
198
+ send("build_#{name}", attrs, options)
178
199
  end
179
200
  end
180
201
  end
@@ -11,8 +11,7 @@ module Mongoid #:nodoc:
11
11
  :destroy,
12
12
  :save,
13
13
  :update,
14
- :validate,
15
- :terminator => false
14
+ :validate
16
15
  end
17
16
  end
18
17
  end
@@ -1,13 +1,12 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/collections/operations"
3
3
  require "mongoid/collections/cyclic_iterator"
4
- require "mongoid/collections/mimic"
5
4
  require "mongoid/collections/master"
6
5
  require "mongoid/collections/slaves"
7
6
 
8
7
  module Mongoid #:nodoc
8
+ # The Mongoid wrapper to the Mongo Ruby driver's collection object.
9
9
  class Collection
10
- include Collections::Mimic
11
10
  attr_reader :counter, :name
12
11
 
13
12
  # All write operations should delegate to the master connection. These
@@ -16,7 +15,9 @@ module Mongoid #:nodoc
16
15
  # Example:
17
16
  #
18
17
  # <tt>collection.save({ :name => "Al" })</tt>
19
- proxy(:master, Collections::Operations::PROXIED)
18
+ Collections::Operations::PROXIED.each do |name|
19
+ define_method(name) { |*args| master.send(name, *args) }
20
+ end
20
21
 
21
22
  # Determines where to send the next read query. If the slaves are not
22
23
  # defined then send to master. If the read counter is under the configured
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ # The collections module is used for providing functionality around setting
4
+ # up and updating collections.
5
+ module Collections
6
+ extend ActiveSupport::Concern
7
+ included do
8
+ cattr_accessor :_collection, :collection_name
9
+ self.collection_name = self.name.collectionize
10
+ delegate :collection, :to => "self.class"
11
+ end
12
+
13
+ module ClassMethods #:nodoc:
14
+ # Returns the collection associated with this +Document+. If the
15
+ # document is embedded, there will be no collection associated
16
+ # with it.
17
+ #
18
+ # Returns: <tt>Mongo::Collection</tt>
19
+ def collection
20
+ raise Errors::InvalidCollection.new(self) if embedded?
21
+ self._collection || set_collection
22
+ add_indexes; self._collection
23
+ end
24
+
25
+ # Macro for setting the collection name to store in.
26
+ #
27
+ # Example:
28
+ #
29
+ # <tt>Person.store_in :populdation</tt>
30
+ def store_in(name)
31
+ self.collection_name = name.to_s
32
+ set_collection
33
+ end
34
+
35
+ protected
36
+ def set_collection
37
+ self._collection = Mongoid::Collection.new(self, self.collection_name)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,7 +2,6 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Collections #:nodoc:
4
4
  class Master
5
- include Mimic
6
5
 
7
6
  attr_reader :collection
8
7
 
@@ -12,7 +11,9 @@ module Mongoid #:nodoc:
12
11
  # Example:
13
12
  #
14
13
  # <tt>collection.save({ :name => "Al" })</tt>
15
- proxy(:collection, Operations::ALL)
14
+ Operations::ALL.each do |name|
15
+ define_method(name) { |*args| collection.send(name, *args) }
16
+ end
16
17
 
17
18
  # Create the new database writer. Will create a collection from the
18
19
  # master database.
@@ -2,7 +2,6 @@
2
2
  module Mongoid #:nodoc:
3
3
  module Collections #:nodoc:
4
4
  class Slaves
5
- include Mimic
6
5
 
7
6
  attr_reader :iterator
8
7
 
@@ -12,7 +11,9 @@ module Mongoid #:nodoc:
12
11
  # Example:
13
12
  #
14
13
  # <tt>collection.save({ :name => "Al" })</tt>
15
- proxy(:collection, Operations::READ)
14
+ Operations::READ.each do |name|
15
+ define_method(name) { |*args| collection.send(name, *args) }
16
+ end
16
17
 
17
18
  # Is the collection of slaves empty or not?
18
19
  #
@@ -8,10 +8,12 @@ module Mongoid #:nodoc
8
8
  include ActiveModel::Conversion
9
9
  include ActiveModel::Naming
10
10
  include ActiveModel::Serialization
11
+ include ActiveModel::Serializers::JSON
11
12
  include Mongoid::Associations
12
13
  include Mongoid::Attributes
13
14
  include Mongoid::Callbacks
14
- include Mongoid::Commands
15
+ include Mongoid::Collections
16
+ include Mongoid::Dirty
15
17
  include Mongoid::Extras
16
18
  include Mongoid::Fields
17
19
  include Mongoid::Indexes
@@ -19,6 +21,7 @@ module Mongoid #:nodoc
19
21
  include Mongoid::Memoization
20
22
  include Mongoid::Observable
21
23
  include Mongoid::Paths
24
+ include Mongoid::Persistence
22
25
  include Mongoid::State
23
26
  include Mongoid::Validations
24
27
  extend ActiveModel::Translation
@@ -1,4 +1,6 @@
1
1
  # encoding: utf-8
2
+ require "uri"
3
+
2
4
  module Mongoid #:nodoc
3
5
  class Config #:nodoc
4
6
  include Singleton
@@ -8,23 +10,45 @@ module Mongoid #:nodoc
8
10
  :reconnect_time,
9
11
  :parameterize_keys,
10
12
  :persist_in_safe_mode,
11
- :persist_types,
12
13
  :raise_not_found_error,
13
- :use_object_ids
14
+ :use_object_ids,
15
+ :skip_version_check
14
16
 
15
17
  # Defaults the configuration options to true.
16
18
  def initialize
17
- @allow_dynamic_fields = true
18
- @parameterize_keys = true
19
- @persist_in_safe_mode = true
20
- @persist_types = true
21
- @raise_not_found_error = true
22
- @reconnect_time = 3
23
- @use_object_ids = false
19
+ reset
20
+ end
21
+
22
+ # Sets whether the times returned from the database are in UTC or local time.
23
+ # If you omit this setting, then times will be returned in
24
+ # the local time zone.
25
+ #
26
+ # Example:
27
+ #
28
+ # <tt>Config.use_utc = true</tt>
29
+ #
30
+ # Returns:
31
+ #
32
+ # A boolean
33
+ def use_utc=(value)
34
+ @use_utc = value || false
24
35
  end
25
36
 
26
- # Sets the Mongo::DB master database to be used. If the object trying to me
27
- # set is not a valid +Mongo::DB+, then an error will be raise.
37
+ # Returns whether times are return from the database in UTC. If
38
+ # this setting is false, then times will be returned in the local time zone.
39
+ #
40
+ # Example:
41
+ #
42
+ # <tt>Config.use_utc</tt>
43
+ #
44
+ # Returns:
45
+ #
46
+ # A boolean
47
+ attr_reader :use_utc
48
+ alias_method :use_utc?, :use_utc
49
+
50
+ # Sets the Mongo::DB master database to be used. If the object trying to be
51
+ # set is not a valid +Mongo::DB+, then an error will be raised.
28
52
  #
29
53
  # Example:
30
54
  #
@@ -34,7 +58,7 @@ module Mongoid #:nodoc
34
58
  #
35
59
  # The Master DB instance.
36
60
  def master=(db)
37
- raise Errors::InvalidDatabase.new(db) unless db.kind_of?(Mongo::DB)
61
+ check_database!(db)
38
62
  @master = db
39
63
  end
40
64
 
@@ -66,7 +90,10 @@ module Mongoid #:nodoc
66
90
  #
67
91
  # The slaves DB instances.
68
92
  def slaves=(dbs)
69
- dbs.each { |db| raise Errors::InvalidDatabase.new(db) unless db.kind_of?(Mongo::DB) }
93
+ return unless dbs
94
+ dbs.each do |db|
95
+ check_database!(db)
96
+ end
70
97
  @slaves = dbs
71
98
  end
72
99
 
@@ -82,5 +109,128 @@ module Mongoid #:nodoc
82
109
  def slaves
83
110
  @slaves
84
111
  end
112
+
113
+ # Return field names that could cause destructive things to happen if
114
+ # defined in a Mongoid::Document
115
+ #
116
+ # Example:
117
+ #
118
+ # <tt>Config.destructive_fields</tt>
119
+ #
120
+ # Returns:
121
+ #
122
+ # An array of bad field names.
123
+ def destructive_fields
124
+ @destructive_fields ||= lambda {
125
+ klass = Class.new do
126
+ include Mongoid::Document
127
+ end
128
+ klass.instance_methods(true).collect { |method| method.to_s }
129
+ }.call
130
+ end
131
+
132
+ # Configure mongoid from a hash that was usually parsed out of yml.
133
+ #
134
+ # Example:
135
+ #
136
+ # <tt>Mongoid::Config.instance.from_hash({})</tt>
137
+ def from_hash(settings)
138
+ _master(settings)
139
+ _slaves(settings)
140
+ settings.except("database").each_pair do |name, value|
141
+ send("#{name}=", value) if respond_to?(name)
142
+ end
143
+ end
144
+
145
+ # Reset the configuration options to the defaults.
146
+ #
147
+ # Example:
148
+ #
149
+ # <tt>config.reset</tt>
150
+ def reset
151
+ @allow_dynamic_fields = true
152
+ @parameterize_keys = true
153
+ @persist_in_safe_mode = true
154
+ @raise_not_found_error = true
155
+ @reconnect_time = 3
156
+ @use_object_ids = false
157
+ @skip_version_check = false
158
+ @time_zone = nil
159
+ end
160
+
161
+ protected
162
+
163
+ # Check if the database is valid and the correct version.
164
+ #
165
+ # Example:
166
+ #
167
+ # <tt>config.check_database!</tt>
168
+ def check_database!(database)
169
+ raise Errors::InvalidDatabase.new(database) unless database.kind_of?(Mongo::DB)
170
+ unless Mongoid.skip_version_check
171
+ version = database.connection.server_version
172
+ raise Errors::UnsupportedVersion.new(version) if version < Mongoid::MONGODB_VERSION
173
+ end
174
+ end
175
+
176
+ # Get a Rails logger or stdout logger.
177
+ #
178
+ # Example:
179
+ #
180
+ # <tt>config.logger</tt>
181
+ def logger
182
+ defined?(Rails) ? Rails.logger : Logger.new($stdout)
183
+ end
184
+
185
+ # Get a master database from settings.
186
+ #
187
+ # Example:
188
+ #
189
+ # <tt>config._master({}, "test")</tt>
190
+ def _master(settings)
191
+ mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
192
+
193
+ name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
194
+ host = settings["host"] || mongo_uri.host || "localhost"
195
+ port = settings["port"] || mongo_uri.port || 27017
196
+ username = settings["username"] || mongo_uri.user
197
+ password = settings["password"] || mongo_uri.password
198
+
199
+ connection = Mongo::Connection.new(host, port, :logger => logger)
200
+ if username || password
201
+ connection.add_auth(name, username, password)
202
+ connection.apply_saved_authentication
203
+ end
204
+ self.master = connection.db(name)
205
+ end
206
+
207
+ # Get a bunch-o-slaves from settings and names.
208
+ #
209
+ # Example:
210
+ #
211
+ # <tt>config._slaves({}, "test")</tt>
212
+ def _slaves(settings)
213
+ mongo_uri = settings["uri"].present? ? URI.parse(settings["uri"]) : OpenStruct.new
214
+ name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
215
+ self.slaves = []
216
+ slaves = settings["slaves"]
217
+ slaves.to_a.each do |slave|
218
+ slave_uri = slave["uri"].present? ? URI.parse(slave["uri"]) : OpenStruct.new
219
+ slave_username = slave["username"] || slave_uri.user
220
+ slave_password = slave["password"] || slave_uri.password
221
+
222
+ slave_connection = Mongo::Connection.new(
223
+ slave["host"] || slave_uri.host || "localhost",
224
+ slave["port"] || slave_uri.port,
225
+ :slave_ok => true
226
+ )
227
+
228
+ if slave_username || slave_password
229
+ slave_connection.add_auth(name, slave_username, slave_password)
230
+ slave_connection.apply_saved_authentication
231
+ end
232
+ self.slaves << slave_connection.db(name)
233
+ end
234
+ end
85
235
  end
86
236
  end