mongoid 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +3 -1
- data/Rakefile +3 -2
- data/lib/config/locales/bg.yml +6 -0
- data/lib/config/locales/de.yml +6 -0
- data/lib/config/locales/en-GB.yml +48 -0
- data/lib/config/locales/en.yml +6 -3
- data/lib/config/locales/es.yml +6 -0
- data/lib/config/locales/fr.yml +6 -0
- data/lib/config/locales/hi.yml +39 -0
- data/lib/config/locales/hu.yml +13 -7
- data/lib/config/locales/id.yml +3 -0
- data/lib/config/locales/it.yml +7 -1
- data/lib/config/locales/ja.yml +4 -1
- data/lib/config/locales/kr.yml +9 -34
- data/lib/config/locales/nl.yml +6 -0
- data/lib/config/locales/pl.yml +6 -0
- data/lib/config/locales/pt-BR.yml +6 -0
- data/lib/config/locales/pt.yml +6 -0
- data/lib/config/locales/ro.yml +6 -0
- data/lib/config/locales/ru.yml +6 -0
- data/lib/config/locales/sv.yml +6 -0
- data/lib/config/locales/vi.yml +3 -0
- data/lib/config/locales/zh-CN.yml +6 -0
- data/lib/mongoid.rb +51 -45
- data/lib/mongoid/atomic.rb +145 -0
- data/lib/mongoid/atomic/modifiers.rb +109 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +43 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
- data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
- data/lib/mongoid/atomic/paths/root.rb +40 -0
- data/lib/mongoid/attributes.rb +12 -23
- data/lib/mongoid/attributes/processing.rb +5 -5
- data/lib/mongoid/callbacks.rb +2 -0
- data/lib/mongoid/collection.rb +12 -59
- data/lib/mongoid/collections.rb +23 -20
- data/lib/mongoid/collections/master.rb +6 -4
- data/lib/mongoid/collections/operations.rb +1 -0
- data/lib/mongoid/collections/retry.rb +7 -0
- data/lib/mongoid/components.rb +2 -2
- data/lib/mongoid/config.rb +42 -55
- data/lib/mongoid/config/database.rb +6 -2
- data/lib/mongoid/config/replset_database.rb +7 -3
- data/lib/mongoid/contexts.rb +9 -3
- data/lib/mongoid/contexts/enumerable.rb +7 -3
- data/lib/mongoid/contexts/mongo.rb +139 -101
- data/lib/mongoid/criteria.rb +86 -69
- data/lib/mongoid/criterion/complex.rb +32 -5
- data/lib/mongoid/criterion/inclusion.rb +4 -2
- data/lib/mongoid/criterion/optional.rb +111 -86
- data/lib/mongoid/criterion/selector.rb +8 -4
- data/lib/mongoid/cursor.rb +27 -27
- data/lib/mongoid/dirty.rb +54 -214
- data/lib/mongoid/document.rb +37 -39
- data/lib/mongoid/errors/document_not_found.rb +3 -4
- data/lib/mongoid/errors/invalid_collection.rb +2 -3
- data/lib/mongoid/errors/invalid_database.rb +2 -3
- data/lib/mongoid/errors/invalid_field.rb +2 -3
- data/lib/mongoid/errors/invalid_options.rb +19 -7
- data/lib/mongoid/errors/invalid_type.rb +2 -3
- data/lib/mongoid/errors/mongoid_error.rb +5 -6
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -3
- data/lib/mongoid/errors/unsupported_version.rb +2 -3
- data/lib/mongoid/errors/validations.rb +2 -3
- data/lib/mongoid/extensions.rb +8 -62
- data/lib/mongoid/extensions/array/deletion.rb +29 -0
- data/lib/mongoid/extensions/false_class/equality.rb +14 -1
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +21 -10
- data/lib/mongoid/extensions/hash/scoping.rb +14 -1
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -1
- data/lib/mongoid/extensions/object/reflections.rb +33 -2
- data/lib/mongoid/extensions/object_id/conversions.rb +2 -36
- data/lib/mongoid/extensions/proc/scoping.rb +14 -1
- data/lib/mongoid/extensions/string/conversions.rb +4 -16
- data/lib/mongoid/extensions/string/inflections.rb +35 -14
- data/lib/mongoid/extensions/symbol/inflections.rb +38 -12
- data/lib/mongoid/extensions/true_class/equality.rb +14 -1
- data/lib/mongoid/extras.rb +11 -30
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields.rb +121 -29
- data/lib/mongoid/fields/mappings.rb +36 -0
- data/lib/mongoid/fields/serializable.rb +131 -0
- data/lib/mongoid/fields/serializable/array.rb +64 -0
- data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
- data/lib/mongoid/fields/serializable/bignum.rb +10 -0
- data/lib/mongoid/fields/serializable/binary.rb +11 -0
- data/lib/mongoid/fields/serializable/boolean.rb +44 -0
- data/lib/mongoid/fields/serializable/date.rb +51 -0
- data/lib/mongoid/fields/serializable/date_time.rb +28 -0
- data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
- data/lib/mongoid/fields/serializable/float.rb +33 -0
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +56 -0
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +43 -0
- data/lib/mongoid/fields/serializable/hash.rb +25 -0
- data/lib/mongoid/fields/serializable/integer.rb +33 -0
- data/lib/mongoid/fields/serializable/object.rb +11 -0
- data/lib/mongoid/fields/serializable/object_id.rb +32 -0
- data/lib/mongoid/fields/serializable/range.rb +42 -0
- data/lib/mongoid/fields/serializable/set.rb +42 -0
- data/lib/mongoid/fields/serializable/string.rb +28 -0
- data/lib/mongoid/fields/serializable/symbol.rb +28 -0
- data/lib/mongoid/fields/serializable/time.rb +12 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +12 -0
- data/lib/mongoid/fields/serializable/timekeeping.rb +102 -0
- data/lib/mongoid/finders.rb +61 -37
- data/lib/mongoid/hierarchy.rb +43 -8
- data/lib/mongoid/identity_map.rb +106 -0
- data/lib/mongoid/indexes.rb +17 -1
- data/lib/mongoid/javascript.rb +2 -3
- data/lib/mongoid/keys.rb +10 -21
- data/lib/mongoid/logger.rb +22 -1
- data/lib/mongoid/matchers/all.rb +10 -0
- data/lib/mongoid/matchers/default.rb +1 -1
- data/lib/mongoid/matchers/exists.rb +10 -0
- data/lib/mongoid/matchers/gt.rb +10 -0
- data/lib/mongoid/matchers/gte.rb +10 -0
- data/lib/mongoid/matchers/in.rb +10 -0
- data/lib/mongoid/matchers/lt.rb +10 -0
- data/lib/mongoid/matchers/lte.rb +10 -0
- data/lib/mongoid/matchers/ne.rb +10 -0
- data/lib/mongoid/matchers/nin.rb +10 -0
- data/lib/mongoid/matchers/or.rb +7 -4
- data/lib/mongoid/matchers/size.rb +10 -0
- data/lib/mongoid/multi_database.rb +26 -6
- data/lib/mongoid/multi_parameter_attributes.rb +40 -17
- data/lib/mongoid/named_scope.rb +1 -2
- data/lib/mongoid/nested_attributes.rb +4 -1
- data/lib/mongoid/observer.rb +108 -5
- data/lib/mongoid/paranoia.rb +26 -26
- data/lib/mongoid/persistence.rb +15 -21
- data/lib/mongoid/persistence/atomic.rb +135 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +11 -8
- data/lib/mongoid/persistence/atomic/bit.rb +37 -0
- data/lib/mongoid/persistence/atomic/inc.rb +9 -6
- data/lib/mongoid/persistence/atomic/operation.rb +48 -7
- data/lib/mongoid/persistence/atomic/pop.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +10 -9
- data/lib/mongoid/persistence/atomic/push.rb +8 -5
- data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
- data/lib/mongoid/persistence/atomic/rename.rb +31 -0
- data/lib/mongoid/persistence/atomic/set.rb +30 -0
- data/lib/mongoid/persistence/atomic/unset.rb +28 -0
- data/lib/mongoid/persistence/deletion.rb +32 -0
- data/lib/mongoid/persistence/insertion.rb +41 -0
- data/lib/mongoid/persistence/modification.rb +37 -0
- data/lib/mongoid/persistence/operations.rb +214 -0
- data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
- data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
- data/lib/mongoid/persistence/operations/insert.rb +34 -0
- data/lib/mongoid/persistence/operations/remove.rb +33 -0
- data/lib/mongoid/persistence/operations/update.rb +53 -0
- data/lib/mongoid/railtie.rb +21 -33
- data/lib/mongoid/railties/database.rake +12 -12
- data/lib/mongoid/relations.rb +9 -5
- data/lib/mongoid/relations/accessors.rb +15 -36
- data/lib/mongoid/relations/auto_save.rb +2 -2
- data/lib/mongoid/relations/binding.rb +28 -1
- data/lib/mongoid/relations/bindings/embedded/in.rb +17 -30
- data/lib/mongoid/relations/bindings/embedded/many.rb +16 -21
- data/lib/mongoid/relations/bindings/embedded/one.rb +11 -16
- data/lib/mongoid/relations/bindings/referenced/in.rb +31 -32
- data/lib/mongoid/relations/bindings/referenced/many.rb +19 -61
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -63
- data/lib/mongoid/relations/bindings/referenced/one.rb +18 -26
- data/lib/mongoid/relations/builder.rb +4 -2
- data/lib/mongoid/relations/builders.rb +21 -2
- data/lib/mongoid/relations/builders/embedded/in.rb +5 -1
- data/lib/mongoid/relations/builders/embedded/many.rb +12 -4
- data/lib/mongoid/relations/builders/embedded/one.rb +5 -1
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +2 -2
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/in.rb +2 -5
- data/lib/mongoid/relations/builders/referenced/many.rb +2 -3
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +14 -5
- data/lib/mongoid/relations/builders/referenced/one.rb +2 -3
- data/lib/mongoid/relations/embedded/atomic.rb +2 -2
- data/lib/mongoid/relations/embedded/in.rb +72 -41
- data/lib/mongoid/relations/embedded/many.rb +116 -120
- data/lib/mongoid/relations/embedded/one.rb +59 -41
- data/lib/mongoid/relations/embedded/sort.rb +31 -0
- data/lib/mongoid/relations/macros.rb +28 -24
- data/lib/mongoid/relations/many.rb +10 -103
- data/lib/mongoid/relations/metadata.rb +335 -38
- data/lib/mongoid/relations/one.rb +7 -32
- data/lib/mongoid/relations/options.rb +47 -0
- data/lib/mongoid/relations/proxy.rb +29 -28
- data/lib/mongoid/relations/referenced/batch.rb +2 -3
- data/lib/mongoid/relations/referenced/in.rb +66 -53
- data/lib/mongoid/relations/referenced/many.rb +216 -143
- data/lib/mongoid/relations/referenced/many_to_many.rb +132 -163
- data/lib/mongoid/relations/referenced/one.rb +76 -58
- data/lib/mongoid/relations/synchronization.rb +113 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +329 -0
- data/lib/mongoid/safety.rb +24 -156
- data/lib/mongoid/serialization.rb +21 -0
- data/lib/mongoid/state.rb +34 -0
- data/lib/mongoid/threaded.rb +175 -0
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/validations.rb +3 -7
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +61 -7
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +1 -1
- data/lib/rails/generators/mongoid/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +1 -1
- data/lib/rails/generators/mongoid/observer/templates/{observer.rb → observer.rb.tt} +0 -0
- data/lib/rails/mongoid.rb +17 -17
- metadata +136 -102
- data/lib/mongoid/atomicity.rb +0 -111
- data/lib/mongoid/collections/cyclic_iterator.rb +0 -34
- data/lib/mongoid/collections/slaves.rb +0 -61
- data/lib/mongoid/extensions/array/conversions.rb +0 -23
- data/lib/mongoid/extensions/array/parentization.rb +0 -13
- data/lib/mongoid/extensions/big_decimal/conversions.rb +0 -19
- data/lib/mongoid/extensions/binary/conversions.rb +0 -17
- data/lib/mongoid/extensions/boolean/conversions.rb +0 -27
- data/lib/mongoid/extensions/date/conversions.rb +0 -25
- data/lib/mongoid/extensions/datetime/conversions.rb +0 -12
- data/lib/mongoid/extensions/float/conversions.rb +0 -20
- data/lib/mongoid/extensions/hash/conversions.rb +0 -19
- data/lib/mongoid/extensions/integer/conversions.rb +0 -20
- data/lib/mongoid/extensions/object/conversions.rb +0 -25
- data/lib/mongoid/extensions/range/conversions.rb +0 -25
- data/lib/mongoid/extensions/set/conversions.rb +0 -20
- data/lib/mongoid/extensions/symbol/conversions.rb +0 -21
- data/lib/mongoid/extensions/time_conversions.rb +0 -38
- data/lib/mongoid/field.rb +0 -162
- data/lib/mongoid/paths.rb +0 -61
- data/lib/mongoid/persistence/command.rb +0 -71
- data/lib/mongoid/persistence/insert.rb +0 -53
- data/lib/mongoid/persistence/insert_embedded.rb +0 -43
- data/lib/mongoid/persistence/remove.rb +0 -44
- data/lib/mongoid/persistence/remove_all.rb +0 -40
- data/lib/mongoid/persistence/remove_embedded.rb +0 -48
- data/lib/mongoid/persistence/update.rb +0 -77
- data/lib/mongoid/safe.rb +0 -23
- data/lib/mongoid/validations/referenced.rb +0 -58
@@ -14,11 +14,13 @@ module Mongoid #:nodoc:
|
|
14
14
|
# @example Proxy the driver save.
|
15
15
|
# collection.save({ :name => "Al" })
|
16
16
|
Operations::ALL.each do |name|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
class_eval <<-EOS, __FILE__, __LINE__
|
18
|
+
def #{name}(*args)
|
19
|
+
retry_on_connection_failure do
|
20
|
+
collection.#{name}(*args)
|
21
|
+
end
|
20
22
|
end
|
21
|
-
|
23
|
+
EOS
|
22
24
|
end
|
23
25
|
|
24
26
|
# Create the new database writer. Will create a collection from the
|
@@ -31,9 +31,16 @@ module Mongoid #:nodoc:
|
|
31
31
|
retries += 1
|
32
32
|
raise ex if retries > Mongoid.max_retries_on_connection_failure
|
33
33
|
Kernel.sleep(0.5)
|
34
|
+
log_retry retries
|
34
35
|
retry
|
35
36
|
end
|
36
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def log_retry(retry_number)
|
42
|
+
Mongoid.logger.warn "A Mongo::ConnectionFailure was raised. Retry attempt ##{retry_number}."
|
43
|
+
end
|
37
44
|
end
|
38
45
|
end
|
39
46
|
end
|
data/lib/mongoid/components.rb
CHANGED
@@ -16,7 +16,7 @@ module Mongoid #:nodoc
|
|
16
16
|
include ActiveModel::Observing
|
17
17
|
include ActiveModel::Serializers::JSON
|
18
18
|
include ActiveModel::Serializers::Xml
|
19
|
-
include Mongoid::
|
19
|
+
include Mongoid::Atomic
|
20
20
|
include Mongoid::Attributes
|
21
21
|
include Mongoid::Collections
|
22
22
|
include Mongoid::Copyable
|
@@ -32,7 +32,6 @@ module Mongoid #:nodoc
|
|
32
32
|
include Mongoid::Matchers
|
33
33
|
include Mongoid::NamedScope
|
34
34
|
include Mongoid::NestedAttributes
|
35
|
-
include Mongoid::Paths
|
36
35
|
include Mongoid::Persistence
|
37
36
|
include Mongoid::Relations
|
38
37
|
include Mongoid::Safety
|
@@ -41,5 +40,6 @@ module Mongoid #:nodoc
|
|
41
40
|
include Mongoid::State
|
42
41
|
include Mongoid::Validations
|
43
42
|
include Mongoid::Callbacks
|
43
|
+
include Mongoid::MultiDatabase
|
44
44
|
end
|
45
45
|
end
|
data/lib/mongoid/config.rb
CHANGED
@@ -13,8 +13,9 @@ module Mongoid #:nodoc
|
|
13
13
|
extend self
|
14
14
|
include ActiveModel::Observing
|
15
15
|
|
16
|
-
attr_accessor :master, :
|
16
|
+
attr_accessor :master, :settings, :defaults
|
17
17
|
@settings = {}
|
18
|
+
@defaults = {}
|
18
19
|
|
19
20
|
# Define a configuration option with a default.
|
20
21
|
#
|
@@ -28,22 +29,33 @@ module Mongoid #:nodoc
|
|
28
29
|
#
|
29
30
|
# @since 2.0.0.rc.1
|
30
31
|
def option(name, options = {})
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
defaults[name] = settings[name] = options[:default]
|
33
|
+
|
34
|
+
class_eval <<-RUBY
|
35
|
+
def #{name}
|
36
|
+
settings[#{name.inspect}]
|
37
|
+
end
|
38
|
+
|
39
|
+
def #{name}=(value)
|
40
|
+
settings[#{name.inspect}] = value
|
41
|
+
end
|
42
|
+
|
43
|
+
def #{name}?
|
44
|
+
#{name}
|
45
|
+
end
|
46
|
+
RUBY
|
36
47
|
end
|
37
48
|
|
38
49
|
option :allow_dynamic_fields, :default => true
|
39
50
|
option :autocreate_indexes, :default => false
|
40
51
|
option :binding_defaults, :default => { :binding => false, :continue => true }
|
41
52
|
option :embedded_object_id, :default => true
|
53
|
+
option :identity_map_enabled, :default => false
|
42
54
|
option :include_root_in_json, :default => false
|
43
55
|
option :max_retries_on_connection_failure, :default => 0
|
44
56
|
option :parameterize_keys, :default => true
|
45
57
|
option :persist_in_safe_mode, :default => false
|
46
|
-
option :preload_models, :default =>
|
58
|
+
option :preload_models, :default => false
|
47
59
|
option :raise_not_found_error, :default => true
|
48
60
|
option :skip_version_check, :default => false
|
49
61
|
option :time_zone, :default => nil
|
@@ -125,7 +137,7 @@ module Mongoid #:nodoc
|
|
125
137
|
#
|
126
138
|
# @since 2.0.1
|
127
139
|
def load!(path)
|
128
|
-
environment = defined?(Rails) ? Rails.env : ENV["RACK_ENV"]
|
140
|
+
environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
|
129
141
|
settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
|
130
142
|
if settings.present?
|
131
143
|
from_hash(settings)
|
@@ -139,7 +151,7 @@ module Mongoid #:nodoc
|
|
139
151
|
#
|
140
152
|
# @return [ Logger ] The default Logger instance.
|
141
153
|
def default_logger
|
142
|
-
defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
|
154
|
+
defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : ::Logger.new($stdout)
|
143
155
|
end
|
144
156
|
|
145
157
|
# Returns the logger, or defaults to Rails logger or stdout logger.
|
@@ -177,30 +189,18 @@ module Mongoid #:nodoc
|
|
177
189
|
|
178
190
|
# Sets whether the times returned from the database use the ruby or
|
179
191
|
# the ActiveSupport time zone.
|
180
|
-
# If you omit this setting, then times will use the ruby time zone.
|
181
192
|
#
|
182
|
-
#
|
193
|
+
# @note If you omit this setting, then times will use the ruby time zone.
|
183
194
|
#
|
184
|
-
#
|
195
|
+
# @example Set the time zone config.
|
196
|
+
# Config.use_activesupport_time_zone = true
|
185
197
|
#
|
186
|
-
#
|
198
|
+
# @param [ true, false ] value Whether to use Active Support time zones.
|
187
199
|
#
|
188
|
-
#
|
200
|
+
# @return [ true, false ] The supplied value or false if nil.
|
189
201
|
def use_activesupport_time_zone=(value)
|
190
202
|
@use_activesupport_time_zone = value || false
|
191
203
|
end
|
192
|
-
|
193
|
-
# Sets whether the times returned from the database use the ruby or
|
194
|
-
# the ActiveSupport time zone.
|
195
|
-
# If the setting is false, then times will use the ruby time zone.
|
196
|
-
#
|
197
|
-
# Example:
|
198
|
-
#
|
199
|
-
# <tt>Config.use_activesupport_time_zone</tt>
|
200
|
-
#
|
201
|
-
# Returns:
|
202
|
-
#
|
203
|
-
# A boolean
|
204
204
|
attr_reader :use_activesupport_time_zone
|
205
205
|
alias_method :use_activesupport_time_zone?, :use_activesupport_time_zone
|
206
206
|
|
@@ -265,39 +265,17 @@ module Mongoid #:nodoc
|
|
265
265
|
# @example Reset the configuration options.
|
266
266
|
# config.reset
|
267
267
|
def reset
|
268
|
-
settings.
|
268
|
+
settings.replace(defaults)
|
269
269
|
end
|
270
270
|
|
271
|
-
#
|
272
|
-
|
273
|
-
|
274
|
-
# @example Set the slaves.
|
275
|
-
# config.slaves = [ Mongo::Connection.db("test") ]
|
276
|
-
#
|
277
|
-
# @param [ Array<Mongo::DB> ] dbs The slave databases.
|
278
|
-
#
|
279
|
-
# @raise [ Errors::InvalidDatabase ] If the slaves arent valid objects.
|
280
|
-
#
|
281
|
-
# @return [ Array<Mongo::DB> ] The slave DB instances.
|
282
|
-
def slaves=(dbs)
|
283
|
-
return unless dbs
|
284
|
-
dbs.each do |db|
|
285
|
-
check_database!(db)
|
286
|
-
end
|
287
|
-
@slaves = dbs
|
271
|
+
# @deprecated User replica sets instead.
|
272
|
+
def slaves
|
273
|
+
slave_warning!
|
288
274
|
end
|
289
275
|
|
290
|
-
#
|
291
|
-
|
292
|
-
|
293
|
-
# config.slaves
|
294
|
-
#
|
295
|
-
# @return [ Array<Mongo::DB>, nil ] The slave databases.
|
296
|
-
def slaves
|
297
|
-
unless @slaves
|
298
|
-
@master, @slaves = configure_databases(@settings) if @settings && @settings[:database]
|
299
|
-
end
|
300
|
-
@slaves
|
276
|
+
# @deprecated User replica sets instead.
|
277
|
+
def slaves=(dbs)
|
278
|
+
slave_warning!
|
301
279
|
end
|
302
280
|
|
303
281
|
protected
|
@@ -358,5 +336,14 @@ module Mongoid #:nodoc
|
|
358
336
|
end
|
359
337
|
end
|
360
338
|
end
|
339
|
+
|
340
|
+
# Temporarily here so people can move to replica sets.
|
341
|
+
def slave_warning!
|
342
|
+
warn(
|
343
|
+
"Using Mongoid for traditional slave databases will be removed in the " +
|
344
|
+
"next release in preference of replica sets. Please change your setup " +
|
345
|
+
"accordingly."
|
346
|
+
)
|
347
|
+
end
|
361
348
|
end
|
362
349
|
end
|
@@ -6,6 +6,9 @@ module Mongoid #:nodoc:
|
|
6
6
|
# database from options.
|
7
7
|
class Database < Hash
|
8
8
|
|
9
|
+
# keys to remove from self to not pass through to Mongo::Connection
|
10
|
+
PRIVATE_OPTIONS = %w(uri database username password)
|
11
|
+
|
9
12
|
# Configure the database connections. This will return an array
|
10
13
|
# containing the master and an array of slaves.
|
11
14
|
#
|
@@ -142,11 +145,12 @@ module Mongoid #:nodoc:
|
|
142
145
|
#
|
143
146
|
# @since 2.0.0.rc.1
|
144
147
|
def optional(slave = false)
|
145
|
-
{
|
148
|
+
({
|
146
149
|
:pool_size => pool_size,
|
147
150
|
:logger => Mongoid::Logger.new,
|
148
151
|
:slave_ok => slave
|
149
|
-
}
|
152
|
+
}).merge(self).reject { |k,v| PRIVATE_OPTIONS.include? k }.
|
153
|
+
inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo} # mongo likes symbols
|
150
154
|
end
|
151
155
|
|
152
156
|
# Get a Mongo compliant URI for the database connection.
|
@@ -14,9 +14,13 @@ module Mongoid #:nodoc:
|
|
14
14
|
#
|
15
15
|
# @since 2.0.0.rc.5
|
16
16
|
def configure
|
17
|
-
#yes, construction is weird but the driver wants
|
18
|
-
#
|
19
|
-
|
17
|
+
# yes, construction is weird but the driver wants
|
18
|
+
# "A list of host-port pairs ending with a hash containing any options"
|
19
|
+
# mongo likes symbols
|
20
|
+
options = self.inject({ :logger => Mongoid::Logger.new }) do |memo, (k, v)|
|
21
|
+
memo[k.to_sym] = v
|
22
|
+
memo
|
23
|
+
end
|
20
24
|
connection = Mongo::ReplSetConnection.new(*(hosts << options))
|
21
25
|
|
22
26
|
if authenticating?
|
data/lib/mongoid/contexts.rb
CHANGED
@@ -4,15 +4,21 @@ require "mongoid/contexts/mongo"
|
|
4
4
|
|
5
5
|
module Mongoid
|
6
6
|
module Contexts
|
7
|
+
extend self
|
8
|
+
|
7
9
|
# Determines the context to be used for this criteria. If the class is an
|
8
10
|
# embedded document, then the context will be the array in the has_many
|
9
11
|
# association it is in. If the class is a root, then the database itself
|
10
12
|
# will be the context.
|
11
13
|
#
|
12
|
-
#
|
14
|
+
# @example Get the context for the criteria.
|
15
|
+
# Contexts.context_for(criteria)
|
16
|
+
#
|
17
|
+
# @param [ Criteria ] criteria The criteria to use.
|
18
|
+
# @param [ true, false ] embedded Whether this is on embedded documents.
|
13
19
|
#
|
14
|
-
#
|
15
|
-
def
|
20
|
+
# @return [ Enumerable, Mongo ] The appropriate context.
|
21
|
+
def context_for(criteria, embedded = false)
|
16
22
|
embedded ? Enumerable.new(criteria) : Mongo.new(criteria)
|
17
23
|
end
|
18
24
|
end
|
@@ -56,7 +56,9 @@ module Mongoid #:nodoc:
|
|
56
56
|
def delete_all
|
57
57
|
atomically(:$pull) do
|
58
58
|
set_collection
|
59
|
-
count.tap
|
59
|
+
count.tap do
|
60
|
+
filter.each { |doc| doc.delete }
|
61
|
+
end
|
60
62
|
end
|
61
63
|
end
|
62
64
|
alias :delete :delete_all
|
@@ -72,7 +74,9 @@ module Mongoid #:nodoc:
|
|
72
74
|
def destroy_all
|
73
75
|
atomically(:$pull) do
|
74
76
|
set_collection
|
75
|
-
count.tap
|
77
|
+
count.tap do
|
78
|
+
filter.each { |doc| doc.destroy }
|
79
|
+
end
|
76
80
|
end
|
77
81
|
end
|
78
82
|
alias :destroy :destroy_all
|
@@ -252,7 +256,7 @@ module Mongoid #:nodoc:
|
|
252
256
|
#
|
253
257
|
# @return [ Collection ] The root collection.
|
254
258
|
def set_collection
|
255
|
-
root = documents.first._root
|
259
|
+
root = documents.first.try(:_root)
|
256
260
|
@collection = root.collection if root && !root.embedded?
|
257
261
|
end
|
258
262
|
|
@@ -6,18 +6,34 @@ module Mongoid #:nodoc:
|
|
6
6
|
|
7
7
|
delegate :klass, :options, :field_list, :selector, :to => :criteria
|
8
8
|
|
9
|
+
# Perform an add to set on the matching documents.
|
10
|
+
#
|
11
|
+
# @example Add to set on all matching.
|
12
|
+
# Person.where(:name => "Alex").add_to_set(:aliases, "value")
|
13
|
+
#
|
14
|
+
# @param [ String ] field The field to add to.
|
15
|
+
# @param [ Object ] value The value to add.
|
16
|
+
#
|
17
|
+
# @return [ Object ] The update value.
|
18
|
+
#
|
19
|
+
# @since 2.1.0
|
20
|
+
def add_to_set(field, value)
|
21
|
+
klass.collection.update(
|
22
|
+
selector,
|
23
|
+
{ "$addToSet" => { field => value } },
|
24
|
+
:multi => true
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
9
28
|
# Aggregate the context. This will take the internally built selector and options
|
10
29
|
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
11
30
|
# collection itself will be retrieved from the class provided, and once the
|
12
31
|
# query has returned it will provided a grouping of keys with counts.
|
13
32
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# <tt>context.aggregate</tt>
|
33
|
+
# @example Aggreate the context.
|
34
|
+
# context.aggregate
|
17
35
|
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# A +Hash+ with field values as keys, counts as values
|
36
|
+
# @return [ Hash ] A +Hash+ with field values as keys, counts as values
|
21
37
|
def aggregate
|
22
38
|
klass.collection.group(
|
23
39
|
:key => field_list,
|
@@ -34,13 +50,12 @@ module Mongoid #:nodoc:
|
|
34
50
|
# collection itself will be retrieved from the class provided, and once the
|
35
51
|
# query has returned it will provided a grouping of keys with averages.
|
36
52
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# <tt>context.avg(:age)</tt>
|
53
|
+
# @example Get the average for a field.
|
54
|
+
# context.avg(:age)
|
40
55
|
#
|
41
|
-
#
|
56
|
+
# @param [ Symbol ] field The field to get the average for.
|
42
57
|
#
|
43
|
-
# A numeric value that is the average.
|
58
|
+
# @return [ Numeric ] A numeric value that is the average.
|
44
59
|
def avg(field)
|
45
60
|
total = sum(field)
|
46
61
|
total ? (total / count) : nil
|
@@ -49,9 +64,10 @@ module Mongoid #:nodoc:
|
|
49
64
|
# Determine if the context is empty or blank given the criteria. Will
|
50
65
|
# perform a quick has_one asking only for the id.
|
51
66
|
#
|
52
|
-
#
|
67
|
+
# @example Is the context empty?
|
68
|
+
# context.blank?a
|
53
69
|
#
|
54
|
-
#
|
70
|
+
# @return [ true, false ] True if blank.
|
55
71
|
def blank?
|
56
72
|
klass.collection.find_one(selector, { :fields => [ :_id ] }).nil?
|
57
73
|
end
|
@@ -102,9 +118,12 @@ module Mongoid #:nodoc:
|
|
102
118
|
# Gets an array of distinct values for the supplied field across the
|
103
119
|
# entire collection or the susbset given the criteria.
|
104
120
|
#
|
105
|
-
#
|
121
|
+
# @example Get the distinct values.
|
122
|
+
# context.distinct(:title)
|
123
|
+
#
|
124
|
+
# @param [ Symbol ] field The field to get the values for.
|
106
125
|
#
|
107
|
-
# <
|
126
|
+
# @return [ Array<Object> ] The distinct values for the field.
|
108
127
|
def distinct(field)
|
109
128
|
klass.collection.distinct(field, selector)
|
110
129
|
end
|
@@ -114,29 +133,35 @@ module Mongoid #:nodoc:
|
|
114
133
|
# collection itself will be retrieved from the class provided, and once the
|
115
134
|
# query has returned new documents of the type of class provided will be instantiated.
|
116
135
|
#
|
117
|
-
#
|
136
|
+
# @example Execute the criteria on the context.
|
137
|
+
# context.execute
|
118
138
|
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
# Returns:
|
122
|
-
#
|
123
|
-
# An enumerable +Cursor+.
|
139
|
+
# @return [ Cursor ] An enumerable +Cursor+ of results.
|
124
140
|
def execute
|
125
141
|
klass.collection.find(selector, process_options) || []
|
126
142
|
end
|
127
143
|
|
144
|
+
# Return the first result for the +Context+.
|
145
|
+
#
|
146
|
+
# @example Get the first document.
|
147
|
+
# context.one
|
148
|
+
#
|
149
|
+
# @return [ Document ] The first document in the collection.
|
150
|
+
def first
|
151
|
+
attributes = klass.collection.find_one(selector, process_options)
|
152
|
+
attributes ? Mongoid::Factory.from_db(klass, attributes) : nil
|
153
|
+
end
|
154
|
+
alias :one :first
|
155
|
+
|
128
156
|
# Groups the context. This will take the internally built selector and options
|
129
157
|
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
130
158
|
# collection itself will be retrieved from the class provided, and once the
|
131
159
|
# query has returned it will provided a grouping of keys with objects.
|
132
160
|
#
|
133
|
-
#
|
161
|
+
# @example Get the criteria as a group.
|
162
|
+
# context.group
|
134
163
|
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
# Returns:
|
138
|
-
#
|
139
|
-
# A +Hash+ with field values as keys, arrays of documents as values.
|
164
|
+
# @return [ Hash ] Hash with field values as keys, arrays of documents as values.
|
140
165
|
def group
|
141
166
|
klass.collection.group(
|
142
167
|
:key => field_list,
|
@@ -154,24 +179,23 @@ module Mongoid #:nodoc:
|
|
154
179
|
# Create the new mongo context. This will execute the queries given the
|
155
180
|
# selector and options against the database.
|
156
181
|
#
|
157
|
-
#
|
182
|
+
# @example Create a new context.
|
183
|
+
# Mongoid::Contexts::Mongo.new(criteria)
|
158
184
|
#
|
159
|
-
#
|
185
|
+
# @param [ Criteria ] criteria The criteria to create with.
|
160
186
|
def initialize(criteria)
|
161
187
|
@criteria = criteria
|
162
188
|
if klass.hereditary? && !criteria.selector.keys.include?(:_type)
|
163
189
|
@criteria = criteria.in(:_type => criteria.klass._types)
|
164
190
|
end
|
165
|
-
@criteria.enslave if klass.enslaved?
|
166
191
|
@criteria.cache if klass.cached?
|
167
192
|
end
|
168
193
|
|
169
194
|
# Iterate over each +Document+ in the results. This can take an optional
|
170
195
|
# block to pass to each argument in the results.
|
171
196
|
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
# <tt>context.iterate { |doc| p doc }</tt>
|
197
|
+
# @example Iterate over the results.
|
198
|
+
# context.iterate { |doc| p doc }
|
175
199
|
def iterate(&block)
|
176
200
|
return caching(&block) if criteria.cached?
|
177
201
|
if block_given?
|
@@ -183,18 +207,15 @@ module Mongoid #:nodoc:
|
|
183
207
|
# the collection with the sorting reversed. If no sorting parameters have
|
184
208
|
# been provided it will default to ids.
|
185
209
|
#
|
186
|
-
#
|
210
|
+
# @example Get the last document.
|
211
|
+
# context.last
|
187
212
|
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
# Returns:
|
191
|
-
#
|
192
|
-
# The last document in the collection.
|
213
|
+
# @return [ Document ] The last document in the collection.
|
193
214
|
def last
|
194
215
|
opts = process_options
|
195
|
-
sorting = opts[:sort]
|
196
|
-
sorting
|
197
|
-
opts[:sort] = sorting.
|
216
|
+
sorting = opts[:sort] ||= []
|
217
|
+
sorting << [:_id, :asc]
|
218
|
+
opts[:sort] = sorting.map{ |option| [ option[0], option[1].invert ] }.uniq
|
198
219
|
attributes = klass.collection.find_one(selector, opts)
|
199
220
|
attributes ? Mongoid::Factory.from_db(klass, attributes) : nil
|
200
221
|
end
|
@@ -206,13 +227,12 @@ module Mongoid #:nodoc:
|
|
206
227
|
# collection itself will be retrieved from the class provided, and once the
|
207
228
|
# query has returned it will provided a grouping of keys with sums.
|
208
229
|
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
# <tt>context.max(:age)</tt>
|
230
|
+
# @example Get the max value.
|
231
|
+
# context.max(:age)
|
212
232
|
#
|
213
|
-
#
|
233
|
+
# @param [ Symbol ] field The field to get the max for.
|
214
234
|
#
|
215
|
-
# A numeric max value.
|
235
|
+
# @return [ Numeric ] A numeric max value.
|
216
236
|
def max(field)
|
217
237
|
grouped(:max, field.to_s, Javascript.max)
|
218
238
|
end
|
@@ -224,43 +244,44 @@ module Mongoid #:nodoc:
|
|
224
244
|
# collection itself will be retrieved from the class provided, and once the
|
225
245
|
# query has returned it will provided a grouping of keys with sums.
|
226
246
|
#
|
227
|
-
#
|
247
|
+
# @example Get the min value.
|
248
|
+
# context.min(:age)
|
228
249
|
#
|
229
|
-
#
|
250
|
+
# @param [ Symbol ] field The field to get the min for.
|
230
251
|
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# A numeric minimum value.
|
252
|
+
# @return [ Numeric ] A numeric minimum value.
|
234
253
|
def min(field)
|
235
254
|
grouped(:min, field.to_s, Javascript.min)
|
236
255
|
end
|
237
256
|
|
238
|
-
#
|
257
|
+
# Perform a pull on the matching documents.
|
239
258
|
#
|
240
|
-
#
|
259
|
+
# @example Pull on all matching.
|
260
|
+
# Person.where(:name => "Alex").pull(:aliases, "value")
|
241
261
|
#
|
242
|
-
#
|
262
|
+
# @param [ String ] field The field to pull from.
|
263
|
+
# @param [ Object ] value The value to pull.
|
243
264
|
#
|
244
|
-
#
|
265
|
+
# @return [ Object ] The update value.
|
245
266
|
#
|
246
|
-
#
|
247
|
-
def
|
248
|
-
|
249
|
-
|
267
|
+
# @since 2.1.0
|
268
|
+
def pull(field, value)
|
269
|
+
klass.collection.update(
|
270
|
+
selector,
|
271
|
+
{ "$pull" => { field => value } },
|
272
|
+
:multi => true
|
273
|
+
)
|
250
274
|
end
|
251
275
|
|
252
|
-
alias :first :one
|
253
|
-
|
254
276
|
# Return the first result for the +Context+ and skip it
|
255
277
|
# for successive calls.
|
256
278
|
#
|
257
|
-
#
|
279
|
+
# @example Get the first document and shift.
|
280
|
+
# context.shift
|
258
281
|
#
|
259
|
-
# The first document in the collection.
|
282
|
+
# @return [ Document ] The first document in the collection.
|
260
283
|
def shift
|
261
|
-
|
262
|
-
criteria.skip((options[:skip] || 0) + 1)
|
263
|
-
document
|
284
|
+
first.tap { criteria.skip((options[:skip] || 0) + 1) }
|
264
285
|
end
|
265
286
|
|
266
287
|
# Sum the context.
|
@@ -270,43 +291,16 @@ module Mongoid #:nodoc:
|
|
270
291
|
# collection itself will be retrieved from the class provided, and once the
|
271
292
|
# query has returned it will provided a grouping of keys with sums.
|
272
293
|
#
|
273
|
-
#
|
274
|
-
#
|
275
|
-
# <tt>context.sum(:age)</tt>
|
294
|
+
# @example Get the sum for a field.
|
295
|
+
# context.sum(:age)
|
276
296
|
#
|
277
|
-
#
|
297
|
+
# @param [ Symbol ] field The field who's values to sum.
|
278
298
|
#
|
279
|
-
# A numeric value that is the sum.
|
299
|
+
# @return [ Numeric ] A numeric value that is the sum.
|
280
300
|
def sum(field)
|
281
301
|
grouped(:sum, field.to_s, Javascript.sum)
|
282
302
|
end
|
283
303
|
|
284
|
-
# Common functionality for grouping operations. Currently used by min, max
|
285
|
-
# and sum. Will gsub the field name in the supplied reduce function.
|
286
|
-
def grouped(start, field, reduce)
|
287
|
-
collection = klass.collection.group(
|
288
|
-
:cond => selector,
|
289
|
-
:initial => { start => "start" },
|
290
|
-
:reduce => reduce.gsub("[field]", field)
|
291
|
-
)
|
292
|
-
collection.empty? ? nil : collection.first[start.to_s]
|
293
|
-
end
|
294
|
-
|
295
|
-
# Filters the field list. If no fields have been supplied, then it will be
|
296
|
-
# empty. If fields have been defined then _type will be included as well.
|
297
|
-
def process_options
|
298
|
-
fields = options[:fields]
|
299
|
-
if fields && fields.size > 0 && !fields.include?(:_type)
|
300
|
-
if fields.kind_of?(Hash)
|
301
|
-
fields[:_type] = 1 if fields.first.last != 0 # Not excluding
|
302
|
-
else
|
303
|
-
fields << :type
|
304
|
-
end
|
305
|
-
options[:fields] = fields
|
306
|
-
end
|
307
|
-
options.dup
|
308
|
-
end
|
309
|
-
|
310
304
|
# Very basic update that will perform a simple atomic $set of the
|
311
305
|
# attributes provided in the hash. Can be expanded to later for more
|
312
306
|
# robust functionality.
|
@@ -321,15 +315,19 @@ module Mongoid #:nodoc:
|
|
321
315
|
klass.collection.update(
|
322
316
|
selector,
|
323
317
|
{ "$set" => attributes },
|
324
|
-
:multi => true
|
325
|
-
|
326
|
-
|
318
|
+
Safety.merge_safety_options(:multi => true)
|
319
|
+
).tap do
|
320
|
+
Threaded.clear_safety_options!
|
321
|
+
end
|
327
322
|
end
|
328
323
|
alias :update :update_all
|
329
324
|
|
330
325
|
protected
|
331
326
|
|
332
327
|
# Iterate over each +Document+ in the results and cache the collection.
|
328
|
+
#
|
329
|
+
# @example Execute with caching.
|
330
|
+
# context.caching
|
333
331
|
def caching(&block)
|
334
332
|
if defined? @collection
|
335
333
|
@collection.each(&block)
|
@@ -341,6 +339,46 @@ module Mongoid #:nodoc:
|
|
341
339
|
end
|
342
340
|
end
|
343
341
|
end
|
342
|
+
|
343
|
+
# Common functionality for grouping operations. Currently used by min, max
|
344
|
+
# and sum. Will gsub the field name in the supplied reduce function.
|
345
|
+
#
|
346
|
+
# @example Execute the group function.
|
347
|
+
# context.group(0, :avg, "")
|
348
|
+
#
|
349
|
+
# @param [ Object ] start The value to start the map/reduce with.
|
350
|
+
# @param [ String ] field The field to aggregate.
|
351
|
+
# @param [ String ] reduce The reduce JS function.
|
352
|
+
#
|
353
|
+
# @return [ Numeric ] A numeric result.
|
354
|
+
def grouped(start, field, reduce)
|
355
|
+
collection = klass.collection.group(
|
356
|
+
:cond => selector,
|
357
|
+
:initial => { start => "start" },
|
358
|
+
:reduce => reduce.gsub("[field]", field)
|
359
|
+
)
|
360
|
+
collection.empty? ? nil : collection.first[start.to_s]
|
361
|
+
end
|
362
|
+
|
363
|
+
# Filters the field list. If no fields have been supplied, then it will be
|
364
|
+
# empty. If fields have been defined then _type will be included as well.
|
365
|
+
#
|
366
|
+
# @example Process the field list.
|
367
|
+
# context.process_options
|
368
|
+
#
|
369
|
+
# @return [ Hash ] The options.
|
370
|
+
def process_options
|
371
|
+
fields = options[:fields]
|
372
|
+
if fields && fields.size > 0 && !fields.include?(:_type)
|
373
|
+
if fields.kind_of?(Hash)
|
374
|
+
fields[:_type] = 1 if fields.first.last != 0 # Not excluding
|
375
|
+
else
|
376
|
+
fields << :type
|
377
|
+
end
|
378
|
+
options[:fields] = fields
|
379
|
+
end
|
380
|
+
options.dup
|
381
|
+
end
|
344
382
|
end
|
345
383
|
end
|
346
384
|
end
|