mongoid-multi-db 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +615 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +49 -0
- data/lib/config/locales/bg.yml +54 -0
- data/lib/config/locales/de.yml +54 -0
- data/lib/config/locales/en-GB.yml +55 -0
- data/lib/config/locales/en.yml +55 -0
- data/lib/config/locales/es.yml +52 -0
- data/lib/config/locales/fr.yml +55 -0
- data/lib/config/locales/hi.yml +46 -0
- data/lib/config/locales/hu.yml +57 -0
- data/lib/config/locales/id.yml +55 -0
- data/lib/config/locales/it.yml +52 -0
- data/lib/config/locales/ja.yml +50 -0
- data/lib/config/locales/kr.yml +47 -0
- data/lib/config/locales/nl.yml +52 -0
- data/lib/config/locales/pl.yml +52 -0
- data/lib/config/locales/pt-BR.yml +53 -0
- data/lib/config/locales/pt.yml +53 -0
- data/lib/config/locales/ro.yml +59 -0
- data/lib/config/locales/ru.yml +54 -0
- data/lib/config/locales/sv.yml +53 -0
- data/lib/config/locales/vi.yml +55 -0
- data/lib/config/locales/zh-CN.yml +46 -0
- data/lib/mongoid.rb +148 -0
- data/lib/mongoid/atomic.rb +230 -0
- data/lib/mongoid/atomic/modifiers.rb +243 -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 +234 -0
- data/lib/mongoid/attributes/processing.rb +146 -0
- data/lib/mongoid/callbacks.rb +135 -0
- data/lib/mongoid/collection.rb +153 -0
- data/lib/mongoid/collection_proxy.rb +59 -0
- data/lib/mongoid/collections.rb +120 -0
- data/lib/mongoid/collections/master.rb +45 -0
- data/lib/mongoid/collections/operations.rb +44 -0
- data/lib/mongoid/collections/retry.rb +46 -0
- data/lib/mongoid/components.rb +96 -0
- data/lib/mongoid/config.rb +347 -0
- data/lib/mongoid/config/database.rb +186 -0
- data/lib/mongoid/config/replset_database.rb +82 -0
- data/lib/mongoid/connection_proxy.rb +30 -0
- data/lib/mongoid/contexts.rb +25 -0
- data/lib/mongoid/contexts/enumerable.rb +288 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +409 -0
- data/lib/mongoid/copyable.rb +48 -0
- data/lib/mongoid/criteria.rb +418 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +84 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +305 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +232 -0
- data/lib/mongoid/criterion/selector.rb +153 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/database_proxy.rb +97 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +110 -0
- data/lib/mongoid/document.rb +280 -0
- data/lib/mongoid/errors.rb +17 -0
- data/lib/mongoid/errors/callback.rb +26 -0
- data/lib/mongoid/errors/document_not_found.rb +28 -0
- data/lib/mongoid/errors/eager_load.rb +25 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_database.rb +19 -0
- data/lib/mongoid/errors/invalid_field.rb +18 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_time.rb +25 -0
- data/lib/mongoid/errors/invalid_type.rb +25 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +26 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +20 -0
- data/lib/mongoid/errors/validations.rb +23 -0
- data/lib/mongoid/extensions.rb +82 -0
- data/lib/mongoid/extensions/array/deletion.rb +29 -0
- data/lib/mongoid/extensions/false_class/equality.rb +26 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
- data/lib/mongoid/extensions/hash/scoping.rb +25 -0
- data/lib/mongoid/extensions/integer/checks.rb +23 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
- data/lib/mongoid/extensions/object/checks.rb +29 -0
- data/lib/mongoid/extensions/object/reflections.rb +48 -0
- data/lib/mongoid/extensions/object/substitutable.rb +15 -0
- data/lib/mongoid/extensions/object/yoda.rb +44 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
- data/lib/mongoid/extensions/proc/scoping.rb +25 -0
- data/lib/mongoid/extensions/string/checks.rb +36 -0
- data/lib/mongoid/extensions/string/conversions.rb +22 -0
- data/lib/mongoid/extensions/string/inflections.rb +118 -0
- data/lib/mongoid/extensions/symbol/checks.rb +23 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
- data/lib/mongoid/extensions/true_class/equality.rb +26 -0
- data/lib/mongoid/extras.rb +31 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +332 -0
- data/lib/mongoid/fields/mappings.rb +41 -0
- data/lib/mongoid/fields/serializable.rb +201 -0
- data/lib/mongoid/fields/serializable/array.rb +49 -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 +43 -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 +32 -0
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
- data/lib/mongoid/fields/serializable/hash.rb +11 -0
- data/lib/mongoid/fields/serializable/integer.rb +44 -0
- data/lib/mongoid/fields/serializable/localized.rb +41 -0
- data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
- data/lib/mongoid/fields/serializable/object.rb +11 -0
- data/lib/mongoid/fields/serializable/object_id.rb +31 -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 +27 -0
- data/lib/mongoid/fields/serializable/symbol.rb +27 -0
- data/lib/mongoid/fields/serializable/time.rb +23 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
- data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
- data/lib/mongoid/finders.rb +152 -0
- data/lib/mongoid/hierarchy.rb +120 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/identity_map.rb +119 -0
- data/lib/mongoid/indexes.rb +54 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +20 -0
- data/lib/mongoid/javascript/functions.yml +63 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +144 -0
- data/lib/mongoid/logger.rb +39 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +21 -0
- data/lib/mongoid/matchers/and.rb +30 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +23 -0
- data/lib/mongoid/matchers/gt.rb +21 -0
- data/lib/mongoid/matchers/gte.rb +21 -0
- data/lib/mongoid/matchers/in.rb +21 -0
- data/lib/mongoid/matchers/lt.rb +21 -0
- data/lib/mongoid/matchers/lte.rb +21 -0
- data/lib/mongoid/matchers/ne.rb +21 -0
- data/lib/mongoid/matchers/nin.rb +21 -0
- data/lib/mongoid/matchers/or.rb +33 -0
- data/lib/mongoid/matchers/size.rb +21 -0
- data/lib/mongoid/matchers/strategies.rb +93 -0
- data/lib/mongoid/multi_database.rb +31 -0
- data/lib/mongoid/multi_parameter_attributes.rb +106 -0
- data/lib/mongoid/named_scope.rb +146 -0
- data/lib/mongoid/nested_attributes.rb +54 -0
- data/lib/mongoid/observer.rb +170 -0
- data/lib/mongoid/paranoia.rb +158 -0
- data/lib/mongoid/persistence.rb +264 -0
- data/lib/mongoid/persistence/atomic.rb +223 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
- data/lib/mongoid/persistence/atomic/bit.rb +37 -0
- data/lib/mongoid/persistence/atomic/inc.rb +31 -0
- data/lib/mongoid/persistence/atomic/operation.rb +85 -0
- 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 +34 -0
- data/lib/mongoid/persistence/atomic/push.rb +31 -0
- data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
- data/lib/mongoid/persistence/atomic/rename.rb +31 -0
- data/lib/mongoid/persistence/atomic/sets.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 +211 -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 +64 -0
- data/lib/mongoid/railtie.rb +126 -0
- data/lib/mongoid/railties/database.rake +182 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +144 -0
- data/lib/mongoid/relations/accessors.rb +138 -0
- data/lib/mongoid/relations/auto_save.rb +38 -0
- data/lib/mongoid/relations/binding.rb +26 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +83 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +56 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +26 -0
- data/lib/mongoid/relations/cascading/nullify.rb +18 -0
- data/lib/mongoid/relations/cascading/strategy.rb +26 -0
- data/lib/mongoid/relations/constraint.rb +42 -0
- data/lib/mongoid/relations/conversions.rb +35 -0
- data/lib/mongoid/relations/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +89 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/in.rb +220 -0
- data/lib/mongoid/relations/embedded/many.rb +560 -0
- data/lib/mongoid/relations/embedded/one.rb +206 -0
- data/lib/mongoid/relations/embedded/sort.rb +31 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +135 -0
- data/lib/mongoid/relations/metadata.rb +919 -0
- data/lib/mongoid/relations/nested_builder.rb +75 -0
- data/lib/mongoid/relations/one.rb +36 -0
- data/lib/mongoid/relations/options.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +40 -0
- data/lib/mongoid/relations/proxy.rb +145 -0
- data/lib/mongoid/relations/referenced/batch.rb +72 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +262 -0
- data/lib/mongoid/relations/referenced/many.rb +623 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +272 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +153 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +372 -0
- data/lib/mongoid/reloading.rb +91 -0
- data/lib/mongoid/safety.rb +105 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +134 -0
- data/lib/mongoid/sharding.rb +61 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +530 -0
- data/lib/mongoid/threaded/lifecycle.rb +192 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +24 -0
- data/lib/mongoid/timestamps/timeless.rb +50 -0
- data/lib/mongoid/timestamps/updated.rb +26 -0
- data/lib/mongoid/validations.rb +140 -0
- data/lib/mongoid/validations/associated.rb +46 -0
- data/lib/mongoid/validations/uniqueness.rb +145 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +185 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
- data/lib/rails/generators/mongoid_generator.rb +70 -0
- data/lib/rails/mongoid.rb +91 -0
- metadata +465 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
|
5
|
+
# Contains utility methods for object id conversion.
|
6
|
+
module Conversions
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# Mark the provided object as unconvertable to bson or not, and always
|
10
|
+
# return the provided object.
|
11
|
+
#
|
12
|
+
# @example Flag the object.
|
13
|
+
# Conversions.flag(metadata, 15)
|
14
|
+
#
|
15
|
+
# @param [ Object ] object The object to flag.
|
16
|
+
# @param [ Metadata ] The relation metadata.
|
17
|
+
#
|
18
|
+
# @return [ Object ] The provided object.
|
19
|
+
#
|
20
|
+
# @since 2.3.0
|
21
|
+
def flag(object, metadata)
|
22
|
+
inverse = metadata.inverse_klass
|
23
|
+
if inverse.using_object_ids? || object.is_a?(BSON::ObjectId)
|
24
|
+
object
|
25
|
+
else
|
26
|
+
object.tap do |obj|
|
27
|
+
if obj.is_a?(String)
|
28
|
+
obj.unconvertable_to_bson = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid # :nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
|
5
|
+
# This module provides convenience macros for using cyclic embedded
|
6
|
+
# relations.
|
7
|
+
module Cyclic
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
class_attribute :cyclic
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods #:nodoc:
|
15
|
+
|
16
|
+
# Create a cyclic embedded relation that creates a tree hierarchy for
|
17
|
+
# the document and many embedded child documents.
|
18
|
+
#
|
19
|
+
# @example Set up a recursive embeds many.
|
20
|
+
#
|
21
|
+
# class Role
|
22
|
+
# include Mongoid::Document
|
23
|
+
# recursively_embeds_many
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @example The previous example is a shorcut for this.
|
27
|
+
#
|
28
|
+
# class Role
|
29
|
+
# include Mongoid::Document
|
30
|
+
# embeds_many :child_roles, :class_name => "Role", :cyclic => true
|
31
|
+
# embedded_in :parent_role, :class_name => "Role", :cyclic => true
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# This provides the default nomenclature for accessing a parent document
|
35
|
+
# or its children.
|
36
|
+
#
|
37
|
+
# @since 2.0.0.rc.1
|
38
|
+
def recursively_embeds_many
|
39
|
+
self.cyclic = true
|
40
|
+
embeds_many cyclic_child_name, :class_name => self.name, :cyclic => true
|
41
|
+
embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create a cyclic embedded relation that creates a single self
|
45
|
+
# referencing relationship for a parent and a single child.
|
46
|
+
#
|
47
|
+
# @example Set up a recursive embeds one.
|
48
|
+
#
|
49
|
+
# class Role
|
50
|
+
# include Mongoid::Document
|
51
|
+
# recursively_embeds_one
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# @example The previous example is a shorcut for this.
|
55
|
+
#
|
56
|
+
# class Role
|
57
|
+
# include Mongoid::Document
|
58
|
+
# embeds_one :child_role, :class_name => "Role", :cyclic => true
|
59
|
+
# embedded_in :parent_role, :class_name => "Role", :cyclic => true
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# This provides the default nomenclature for accessing a parent document
|
63
|
+
# or its children.
|
64
|
+
#
|
65
|
+
# @since 2.0.0.rc.1
|
66
|
+
def recursively_embeds_one
|
67
|
+
self.cyclic = true
|
68
|
+
embeds_one cyclic_child_name(false), :class_name => self.name, :cyclic => true
|
69
|
+
embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Determines the parent name given the class.
|
75
|
+
#
|
76
|
+
# @example Determine the parent name.
|
77
|
+
# Role.cyclic_parent_name
|
78
|
+
#
|
79
|
+
# @return [ String ] "parent_" plus the class name underscored.
|
80
|
+
#
|
81
|
+
# @since 2.0.0.rc.1
|
82
|
+
def cyclic_parent_name
|
83
|
+
("parent_" << self.name.demodulize.underscore.singularize).to_sym
|
84
|
+
end
|
85
|
+
|
86
|
+
# Determines the child name given the class.
|
87
|
+
#
|
88
|
+
# @example Determine the child name.
|
89
|
+
# Role.cyclic_child_name
|
90
|
+
#
|
91
|
+
# @param [ true, false ] many Is the a many relation?
|
92
|
+
#
|
93
|
+
# @return [ String ] "child_" plus the class name underscored in
|
94
|
+
# singular or plural form.
|
95
|
+
#
|
96
|
+
# @since 2.0.0.rc.1
|
97
|
+
def cyclic_child_name(many = true)
|
98
|
+
("child_" << self.name.demodulize.underscore.send(many ? :pluralize : :singularize)).to_sym
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/relations/embedded/atomic/operation"
|
3
|
+
require "mongoid/relations/embedded/atomic/pull"
|
4
|
+
require "mongoid/relations/embedded/atomic/push_all"
|
5
|
+
require "mongoid/relations/embedded/atomic/set"
|
6
|
+
require "mongoid/relations/embedded/atomic/unset"
|
7
|
+
|
8
|
+
module Mongoid #:nodoc:
|
9
|
+
module Relations #:nodoc:
|
10
|
+
module Embedded #:nodoc:
|
11
|
+
|
12
|
+
# This module provides the ability for calls to be declared atomic.
|
13
|
+
module Atomic
|
14
|
+
|
15
|
+
MODIFIERS = {
|
16
|
+
:$pull => Pull,
|
17
|
+
:$pushAll => PushAll,
|
18
|
+
:$set => Set,
|
19
|
+
:$unset => Unset
|
20
|
+
}
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Executes a block of commands in an atomic fashion. Mongoid will
|
25
|
+
# intercept all database upserts while in this block and combine them
|
26
|
+
# into a single database call. When the block concludes the atomic
|
27
|
+
# update will occur.
|
28
|
+
#
|
29
|
+
# Since the collection is accessed through the class it would not be
|
30
|
+
# thread safe to give it state so we access the atomic updater via the
|
31
|
+
# current thread.
|
32
|
+
#
|
33
|
+
# @note This operation is not safe when attemping to do illegal updates
|
34
|
+
# for different objects or collections, since the updator is not
|
35
|
+
# scoped on the thread. This is meant for Mongoid internal use only
|
36
|
+
# to keep existing design clean.
|
37
|
+
#
|
38
|
+
# @example Atomically $set multiple saves.
|
39
|
+
# atomically(:$set) do
|
40
|
+
# address_one.save!
|
41
|
+
# address_two.save!
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @example Atomically $pushAll multiple new docs.
|
45
|
+
# atomically(:$pushAll) do
|
46
|
+
# person.addresses.push([ address_one, address_two ])
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# @todo Durran: Move executions to thread local stack.
|
50
|
+
#
|
51
|
+
# @param [ Symbol ] modifier The atomic modifier to perform.
|
52
|
+
# @param [ Proc ] block The block to execute.
|
53
|
+
#
|
54
|
+
# @return [ Object ] The result of the operation.
|
55
|
+
#
|
56
|
+
# @since 2.0.0
|
57
|
+
def atomically(modifier, &block)
|
58
|
+
updater = Threaded.update_consumer(root_class) ||
|
59
|
+
Threaded.set_update_consumer(root_class, MODIFIERS[modifier].new)
|
60
|
+
count_executions do
|
61
|
+
block.call if block
|
62
|
+
end.tap do
|
63
|
+
if @executions.zero?
|
64
|
+
Threaded.set_update_consumer(root_class, nil)
|
65
|
+
updater.execute(collection)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Execute the block, incrementing the executions before the call and
|
71
|
+
# decrementing them after in order to be able to nest blocks within
|
72
|
+
# each other.
|
73
|
+
#
|
74
|
+
# @example Execute and increment.
|
75
|
+
# execute { block.call }
|
76
|
+
#
|
77
|
+
# @param [ Proc ] block The block to call.
|
78
|
+
#
|
79
|
+
# @since 2.0.0
|
80
|
+
def count_executions(&block)
|
81
|
+
@executions ||= 0 and @executions += 1
|
82
|
+
block.call.tap do
|
83
|
+
@executions -=1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Operation
|
8
|
+
attr_accessor :documents, :options, :path, :selector
|
9
|
+
|
10
|
+
# Consumes an execution that was supposed to hit the database, but is
|
11
|
+
# now being deferred to later in favor of a single update.
|
12
|
+
#
|
13
|
+
# @example Consume the operation.
|
14
|
+
# set.consume(
|
15
|
+
# { "_id" => BSON::ObjectId.new },
|
16
|
+
# { "$push" => { "addresses" => { "_id" => "street" } } },
|
17
|
+
# { :multi => false, :safe => true }
|
18
|
+
# )
|
19
|
+
#
|
20
|
+
# @param [ Hash ] selector The document selector.
|
21
|
+
# @param [ Hash ] operations The ops to set in the db.
|
22
|
+
# @param [ Hash ] options The persistence options.
|
23
|
+
#
|
24
|
+
# @option options [ true, false ] :multi Persist multiple at once.
|
25
|
+
# @option options [ true, false ] :safe Persist in safe mode.
|
26
|
+
#
|
27
|
+
# @since 2.0.0
|
28
|
+
def consume(selector, operations, options = {})
|
29
|
+
@consumed, @selector, @options = true, selector, options
|
30
|
+
@documents ||= []
|
31
|
+
parse(operations)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Has this operation consumed any executions?
|
35
|
+
#
|
36
|
+
# @example Is this consumed?
|
37
|
+
# unset.consumed?
|
38
|
+
#
|
39
|
+
# @return [ true, false ] If the operation has consumed anything.
|
40
|
+
#
|
41
|
+
# @since 2.0.0
|
42
|
+
def consumed?
|
43
|
+
!!@consumed
|
44
|
+
end
|
45
|
+
|
46
|
+
# Execute the $pushAll operation on the collection.
|
47
|
+
#
|
48
|
+
# @example Execute the operation.
|
49
|
+
# unset.execute(collection)
|
50
|
+
#
|
51
|
+
# @param [ Collection ] collection The root collection.
|
52
|
+
#
|
53
|
+
# @since 2.0.0
|
54
|
+
def execute(collection)
|
55
|
+
if collection && consumed?
|
56
|
+
collection.update(selector, operations, options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Pull < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The pull operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$pull" =>
|
19
|
+
{ path =>
|
20
|
+
{ "_id" =>
|
21
|
+
{ "$in" => documents.map { |doc| doc["_id"] } }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Parses the incoming operations to get the documents to set.
|
30
|
+
#
|
31
|
+
# @example Parse the operations.
|
32
|
+
# set.parse(
|
33
|
+
# { "$pull" => { "addresses" => { "_id" => "street" } } }
|
34
|
+
# )
|
35
|
+
#
|
36
|
+
# @param [ Hash ] operations The ops to parse.
|
37
|
+
#
|
38
|
+
# @since 2.0.0
|
39
|
+
def parse(operations)
|
40
|
+
modifier = operations.keys.first
|
41
|
+
extract(modifier, operations[modifier])
|
42
|
+
end
|
43
|
+
|
44
|
+
# Extract a document from the operation.
|
45
|
+
#
|
46
|
+
# @example Extract the document.
|
47
|
+
# set.extract({ "$pull" => [{ "_id" => "street" }] })
|
48
|
+
#
|
49
|
+
# @param [ Hash ] operation The op to extract from.
|
50
|
+
#
|
51
|
+
# @since 2.0.0
|
52
|
+
def extract(modifier, operations)
|
53
|
+
@path = operations.keys.first
|
54
|
+
case modifier
|
55
|
+
when "$pull"
|
56
|
+
documents.push(operations[path])
|
57
|
+
when "$pullAll"
|
58
|
+
documents.concat(operations[path])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class PushAll < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The set operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$pushAll" => { path => documents } }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Parses the incoming operations to get the documents to set.
|
24
|
+
#
|
25
|
+
# @example Parse the operations.
|
26
|
+
# set.parse(
|
27
|
+
# { "$push" => { "addresses" => { "_id" => "street" } } }
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @param [ Hash ] operations The ops to parse.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def parse(operations)
|
34
|
+
modifier = operations.keys.first
|
35
|
+
extract(modifier, operations[modifier])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Extract a document from the operation.
|
39
|
+
#
|
40
|
+
# @example Extract the document.
|
41
|
+
# set.extract({ "$pushAll" => [{ "_id" => "street" }] })
|
42
|
+
#
|
43
|
+
# @param [ Hash ] operation The op to extract from.
|
44
|
+
#
|
45
|
+
# @since 2.0.0
|
46
|
+
def extract(modifier, operations)
|
47
|
+
@path = operations.keys.first
|
48
|
+
case modifier
|
49
|
+
when "$push"
|
50
|
+
documents.push(operations[path])
|
51
|
+
when "$pushAll"
|
52
|
+
documents.concat(operations[path])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Set < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The set operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$set" => { path => documents } }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Parses the incoming operations to get the documents to set.
|
24
|
+
#
|
25
|
+
# @example Parse the operations.
|
26
|
+
# set.parse(
|
27
|
+
# { "addresses" => { "$pushAll" => [{ "_id" => "street" }] } }
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @param [ Hash ] operations The ops to parse.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def parse(operations)
|
34
|
+
modifier = operations.keys.first
|
35
|
+
extract(modifier, operations[modifier])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Extract a document from the operation.
|
39
|
+
#
|
40
|
+
# @example Extract the document.
|
41
|
+
# set.extract({ "$pushAll" => [{ "_id" => "street" }] })
|
42
|
+
#
|
43
|
+
# @param [ Hash ] operation The op to extract from.
|
44
|
+
#
|
45
|
+
# @since 2.0.0
|
46
|
+
def extract(modifier, operations)
|
47
|
+
@path = operations.keys.first
|
48
|
+
case modifier
|
49
|
+
when "$push"
|
50
|
+
documents.push(operations[path])
|
51
|
+
when "$pushAll"
|
52
|
+
documents.push(operations[path].first)
|
53
|
+
when "$set"
|
54
|
+
@documents = operations[path]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|