mongoid-braxton 2.0.2
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/LICENSE +20 -0
- data/README.rdoc +50 -0
- data/Rakefile +51 -0
- data/lib/config/locales/bg.yml +41 -0
- data/lib/config/locales/de.yml +41 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +41 -0
- data/lib/config/locales/fr.yml +42 -0
- data/lib/config/locales/hu.yml +44 -0
- data/lib/config/locales/id.yml +46 -0
- data/lib/config/locales/it.yml +39 -0
- data/lib/config/locales/ja.yml +40 -0
- data/lib/config/locales/kr.yml +65 -0
- data/lib/config/locales/nl.yml +39 -0
- data/lib/config/locales/pl.yml +39 -0
- data/lib/config/locales/pt-BR.yml +40 -0
- data/lib/config/locales/pt.yml +40 -0
- data/lib/config/locales/ro.yml +46 -0
- data/lib/config/locales/ru.yml +41 -0
- data/lib/config/locales/sv.yml +40 -0
- data/lib/config/locales/vi.yml +45 -0
- data/lib/config/locales/zh-CN.yml +33 -0
- data/lib/mongoid.rb +140 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +185 -0
- data/lib/mongoid/attributes/processing.rb +145 -0
- data/lib/mongoid/callbacks.rb +23 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/master.rb +37 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/retry.rb +39 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config.rb +349 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +78 -0
- data/lib/mongoid/contexts.rb +19 -0
- data/lib/mongoid/contexts/enumerable.rb +275 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/copyable.rb +46 -0
- data/lib/mongoid/criteria.rb +357 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +198 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +193 -0
- data/lib/mongoid/criterion/selector.rb +143 -0
- data/lib/mongoid/criterion/unconvertable.rb +20 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +253 -0
- data/lib/mongoid/document.rb +284 -0
- data/lib/mongoid/errors.rb +13 -0
- data/lib/mongoid/errors/document_not_found.rb +29 -0
- data/lib/mongoid/errors/invalid_collection.rb +19 -0
- data/lib/mongoid/errors/invalid_database.rb +20 -0
- data/lib/mongoid/errors/invalid_field.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +16 -0
- data/lib/mongoid/errors/invalid_type.rb +26 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +27 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +21 -0
- data/lib/mongoid/errors/validations.rb +24 -0
- data/lib/mongoid/extensions.rb +123 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +25 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/conversions.rb +19 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
- data/lib/mongoid/extensions/object/checks.rb +32 -0
- data/lib/mongoid/extensions/object/conversions.rb +25 -0
- data/lib/mongoid/extensions/object/reflections.rb +17 -0
- data/lib/mongoid/extensions/object/yoda.rb +27 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/range/conversions.rb +25 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +34 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +38 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +42 -0
- data/lib/mongoid/factory.rb +37 -0
- data/lib/mongoid/field.rb +162 -0
- data/lib/mongoid/fields.rb +183 -0
- data/lib/mongoid/finders.rb +127 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +131 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/or.rb +30 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/matchers/strategies.rb +63 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +82 -0
- data/lib/mongoid/named_scope.rb +137 -0
- data/lib/mongoid/nested_attributes.rb +51 -0
- data/lib/mongoid/observer.rb +67 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +240 -0
- data/lib/mongoid/persistence/atomic.rb +88 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
- data/lib/mongoid/persistence/atomic/inc.rb +28 -0
- data/lib/mongoid/persistence/atomic/operation.rb +44 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
- data/lib/mongoid/persistence/atomic/push.rb +28 -0
- data/lib/mongoid/persistence/command.rb +71 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +43 -0
- data/lib/mongoid/persistence/remove.rb +44 -0
- data/lib/mongoid/persistence/remove_all.rb +40 -0
- data/lib/mongoid/persistence/remove_embedded.rb +48 -0
- data/lib/mongoid/persistence/update.rb +77 -0
- data/lib/mongoid/railtie.rb +139 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +107 -0
- data/lib/mongoid/relations/accessors.rb +175 -0
- data/lib/mongoid/relations/auto_save.rb +34 -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 +82 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/builder.rb +42 -0
- data/lib/mongoid/relations/builders.rb +79 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
- data/lib/mongoid/relations/cascading.rb +55 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +19 -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/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +86 -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 +173 -0
- data/lib/mongoid/relations/embedded/many.rb +499 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +215 -0
- data/lib/mongoid/relations/metadata.rb +539 -0
- data/lib/mongoid/relations/nested_builder.rb +68 -0
- data/lib/mongoid/relations/one.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +54 -0
- data/lib/mongoid/relations/proxy.rb +143 -0
- data/lib/mongoid/relations/referenced/batch.rb +71 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +516 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +222 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/safe.rb +23 -0
- data/lib/mongoid/safety.rb +207 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +99 -0
- data/lib/mongoid/sharding.rb +51 -0
- data/lib/mongoid/state.rb +67 -0
- data/lib/mongoid/timestamps.rb +14 -0
- data/lib/mongoid/timestamps/created.rb +31 -0
- data/lib/mongoid/timestamps/updated.rb +33 -0
- data/lib/mongoid/validations.rb +124 -0
- data/lib/mongoid/validations/associated.rb +44 -0
- data/lib/mongoid/validations/referenced.rb +58 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +113 -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 +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +70 -0
- data/lib/rails/mongoid.rb +58 -0
- metadata +406 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
zh-CN:
|
|
2
|
+
mongoid:
|
|
3
|
+
errors:
|
|
4
|
+
messages:
|
|
5
|
+
blank:
|
|
6
|
+
不能为空
|
|
7
|
+
taken:
|
|
8
|
+
已占用
|
|
9
|
+
document_not_found:
|
|
10
|
+
没有发现类是%{klass}id(s)是%{identifiers}的文档
|
|
11
|
+
invalid_database:
|
|
12
|
+
数据库应该是Mongo::DB,而不是%{name}.
|
|
13
|
+
invalid_type:
|
|
14
|
+
在类%{klass}中定义了字段,实际值是%{value}的%{other}.
|
|
15
|
+
unsupported_version:
|
|
16
|
+
MongoDB %{version} 版本已过期,请升级到 %{mongo_version}.
|
|
17
|
+
validations:
|
|
18
|
+
校验失败 - %{errors}.
|
|
19
|
+
invalid_collection:
|
|
20
|
+
不允许直接访问嵌入式的集合%{klass} , 请从文档的根访问集合.
|
|
21
|
+
invalid_field:
|
|
22
|
+
字段的名字不允许为 %{name}. 你不应该定义跟Mongoid内部属性或者方法相同的名字,详细请看Use Document#instance_methods.
|
|
23
|
+
too_many_nested_attribute_records:
|
|
24
|
+
被关联的%{association} 嵌入式属性不能超过 %{limit}.
|
|
25
|
+
embedded_in_must_have_inverse_of:
|
|
26
|
+
embedded_in的关联属性必须包含inverse_of.
|
|
27
|
+
dependent_only_references_one_or_many:
|
|
28
|
+
dependent => destroy|delete 选项只有在references_one或者references_many时候有效.
|
|
29
|
+
association_cant_have_inverse_of:
|
|
30
|
+
在当前的关联中,不允许定义inverse_of去,其只有在embedded_in或者references_many是数组的情况下使用
|
|
31
|
+
unsaved_document:
|
|
32
|
+
You cannot call create or create! through a relational association
|
|
33
|
+
relation (%{document}) who's parent (%{base}) is not already saved.
|
data/lib/mongoid.rb
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2009 - 2011 Durran Jordan and friends.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
# a copy of this software and associated documentation files (the
|
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
# the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be
|
|
14
|
+
# included in all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
require "delegate"
|
|
24
|
+
require "time"
|
|
25
|
+
require "ostruct"
|
|
26
|
+
require "active_support/core_ext"
|
|
27
|
+
require 'active_support/json'
|
|
28
|
+
require "active_support/inflector"
|
|
29
|
+
require "active_support/time_with_zone"
|
|
30
|
+
require "active_model"
|
|
31
|
+
require "active_model/callbacks"
|
|
32
|
+
require "active_model/conversion"
|
|
33
|
+
require "active_model/errors"
|
|
34
|
+
require "active_model/mass_assignment_security"
|
|
35
|
+
require "active_model/naming"
|
|
36
|
+
require "active_model/serialization"
|
|
37
|
+
require "active_model/translation"
|
|
38
|
+
require "active_model/validator"
|
|
39
|
+
require "active_model/validations"
|
|
40
|
+
require "mongo"
|
|
41
|
+
require "mongoid/errors"
|
|
42
|
+
require "mongoid/extensions"
|
|
43
|
+
require "mongoid/safe"
|
|
44
|
+
require "mongoid/relations"
|
|
45
|
+
require "mongoid/atomicity"
|
|
46
|
+
require "mongoid/attributes"
|
|
47
|
+
require "mongoid/callbacks"
|
|
48
|
+
require "mongoid/collection"
|
|
49
|
+
require "mongoid/collections"
|
|
50
|
+
require "mongoid/config"
|
|
51
|
+
require "mongoid/contexts"
|
|
52
|
+
require "mongoid/copyable"
|
|
53
|
+
require "mongoid/criteria"
|
|
54
|
+
require "mongoid/cursor"
|
|
55
|
+
require "mongoid/default_scope"
|
|
56
|
+
require "mongoid/dirty"
|
|
57
|
+
require "mongoid/extras"
|
|
58
|
+
require "mongoid/factory"
|
|
59
|
+
require "mongoid/field"
|
|
60
|
+
require "mongoid/fields"
|
|
61
|
+
require "mongoid/finders"
|
|
62
|
+
require "mongoid/hierarchy"
|
|
63
|
+
require "mongoid/identity"
|
|
64
|
+
require "mongoid/indexes"
|
|
65
|
+
require "mongoid/inspection"
|
|
66
|
+
require "mongoid/javascript"
|
|
67
|
+
require "mongoid/json"
|
|
68
|
+
require "mongoid/keys"
|
|
69
|
+
require "mongoid/logger"
|
|
70
|
+
require "mongoid/matchers"
|
|
71
|
+
require "mongoid/multi_parameter_attributes"
|
|
72
|
+
require "mongoid/multi_database"
|
|
73
|
+
require "mongoid/named_scope"
|
|
74
|
+
require "mongoid/nested_attributes"
|
|
75
|
+
require "mongoid/observer"
|
|
76
|
+
require "mongoid/paths"
|
|
77
|
+
require "mongoid/persistence"
|
|
78
|
+
require "mongoid/safety"
|
|
79
|
+
require "mongoid/scope"
|
|
80
|
+
require "mongoid/serialization"
|
|
81
|
+
require "mongoid/sharding"
|
|
82
|
+
require "mongoid/state"
|
|
83
|
+
require "mongoid/timestamps"
|
|
84
|
+
require "mongoid/validations"
|
|
85
|
+
require "mongoid/versioning"
|
|
86
|
+
require "mongoid/components"
|
|
87
|
+
require "mongoid/paranoia"
|
|
88
|
+
require "mongoid/document"
|
|
89
|
+
|
|
90
|
+
# add railtie
|
|
91
|
+
if defined?(Rails)
|
|
92
|
+
require "mongoid/railtie"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# add english load path by default
|
|
96
|
+
I18n.load_path << File.join(File.dirname(__FILE__), "config", "locales", "en.yml")
|
|
97
|
+
|
|
98
|
+
module Mongoid #:nodoc
|
|
99
|
+
|
|
100
|
+
MONGODB_VERSION = "1.6.0"
|
|
101
|
+
|
|
102
|
+
class << self
|
|
103
|
+
|
|
104
|
+
# Sets the Mongoid configuration options. Best used by passing a block.
|
|
105
|
+
#
|
|
106
|
+
# @example Set up configuration options.
|
|
107
|
+
#
|
|
108
|
+
# Mongoid.configure do |config|
|
|
109
|
+
# name = "mongoid_test"
|
|
110
|
+
# host = "localhost"
|
|
111
|
+
# config.allow_dynamic_fields = false
|
|
112
|
+
# config.master = Mongo::Connection.new.db(name)
|
|
113
|
+
# config.slaves = [
|
|
114
|
+
# Mongo::Connection.new(host, 27018, :slave_ok => true).db(name),
|
|
115
|
+
# Mongo::Connection.new(host, 27019, :slave_ok => true).db(name)
|
|
116
|
+
# ]
|
|
117
|
+
# end
|
|
118
|
+
#
|
|
119
|
+
# @return [ Config ] The configuration obejct.
|
|
120
|
+
def configure
|
|
121
|
+
config = Mongoid::Config
|
|
122
|
+
block_given? ? yield(config) : config
|
|
123
|
+
end
|
|
124
|
+
alias :config :configure
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Take all the public instance methods from the Config singleton and allow
|
|
128
|
+
# them to be accessed through the Mongoid module directly.
|
|
129
|
+
#
|
|
130
|
+
# @example Delegate the configuration methods.
|
|
131
|
+
# Mongoid.database = Mongo::Connection.new.db("test")
|
|
132
|
+
(Mongoid::Config.public_instance_methods(false) +
|
|
133
|
+
ActiveModel::Observing::ClassMethods.public_instance_methods(false)).each do |name|
|
|
134
|
+
(class << self; self; end).class_eval <<-EOT
|
|
135
|
+
def #{name}(*args)
|
|
136
|
+
configure.send("#{name}", *args)
|
|
137
|
+
end
|
|
138
|
+
EOT
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
|
|
4
|
+
# This module contains the logic for supporting atomic operations against the
|
|
5
|
+
# database.
|
|
6
|
+
#
|
|
7
|
+
# @todo Durran: Refactor class out into separate objects for each type of
|
|
8
|
+
# update.
|
|
9
|
+
module Atomicity
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
# Get all the atomic updates that need to happen for the current
|
|
13
|
+
# +Document+. This includes all changes that need to happen in the
|
|
14
|
+
# entire hierarchy that exists below where the save call was made.
|
|
15
|
+
#
|
|
16
|
+
# @note
|
|
17
|
+
# MongoDB does not allow "conflicting modifications" to be
|
|
18
|
+
# performed in a single operation. Conflicting modifications are
|
|
19
|
+
# detected by the 'haveConflictingMod' function in MongoDB.
|
|
20
|
+
# Examination of the code suggests that two modifications (a $set
|
|
21
|
+
# and a $pushAll, for example) conflict if:
|
|
22
|
+
# (1) the key paths being modified are equal.
|
|
23
|
+
# (2) one key path is a prefix of the other.
|
|
24
|
+
# So a $set of 'addresses.0.street' will conflict with a $pushAll
|
|
25
|
+
# to 'addresses', and we will need to split our update into two
|
|
26
|
+
# pieces. We do not, however, attempt to match MongoDB's logic
|
|
27
|
+
# exactly. Instead, we assume that two updates conflict if the
|
|
28
|
+
# first component of the two key paths matches.
|
|
29
|
+
#
|
|
30
|
+
# @example Get the updates that need to occur.
|
|
31
|
+
# person._updates
|
|
32
|
+
#
|
|
33
|
+
# @return [ Hash ] The updates and their modifiers.
|
|
34
|
+
def _updates
|
|
35
|
+
processed = {}
|
|
36
|
+
|
|
37
|
+
_children.inject({ "$set" => _sets, "$pushAll" => {}, :other => {} }) do |updates, child|
|
|
38
|
+
changes = child._sets
|
|
39
|
+
updates["$set"].update(changes)
|
|
40
|
+
unless changes.empty?
|
|
41
|
+
processed[child._conflicting_modification_key] = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if processed.has_key?(child._conflicting_modification_key)
|
|
45
|
+
target = :other
|
|
46
|
+
else
|
|
47
|
+
target = "$pushAll"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
child._pushes.each do |attr, val|
|
|
51
|
+
if updates[target].has_key?(attr)
|
|
52
|
+
updates[target][attr] << val
|
|
53
|
+
else
|
|
54
|
+
updates[target].update({attr => [val]})
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
updates
|
|
58
|
+
end.delete_if do |key, value|
|
|
59
|
+
value.empty?
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
protected
|
|
64
|
+
|
|
65
|
+
# Get the key used to check for conflicting modifications. For now, we
|
|
66
|
+
# just use the first component of _path, and discard the first period
|
|
67
|
+
# and everything that follows.
|
|
68
|
+
#
|
|
69
|
+
# @example Get the key.
|
|
70
|
+
# person._conflicting_modification_key
|
|
71
|
+
#
|
|
72
|
+
# @return [ String ] The conflicting key.
|
|
73
|
+
def _conflicting_modification_key
|
|
74
|
+
_path.sub(/\..*/, '')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Get all the push attributes that need to occur.
|
|
78
|
+
#
|
|
79
|
+
# @example Get the pushes.
|
|
80
|
+
# person._pushes
|
|
81
|
+
#
|
|
82
|
+
# @return [ Hash ] The $pushAll operations.
|
|
83
|
+
def _pushes
|
|
84
|
+
pushable? ? { _path => as_document } : {}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Determine if the document can be pushed.
|
|
88
|
+
#
|
|
89
|
+
# @example Is this pushable?
|
|
90
|
+
# person.pushable?
|
|
91
|
+
#
|
|
92
|
+
# @return [ true, false ] Is the document new and embedded?
|
|
93
|
+
def pushable?
|
|
94
|
+
new_record? && embedded_many? && _parent.persisted?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Get all the attributes that need to be set.
|
|
98
|
+
#
|
|
99
|
+
# @example Get the sets.
|
|
100
|
+
# person._sets
|
|
101
|
+
#
|
|
102
|
+
# @return [ Hash ] The $set operations.
|
|
103
|
+
def _sets
|
|
104
|
+
if changed? && !new_record?
|
|
105
|
+
setters
|
|
106
|
+
else
|
|
107
|
+
embedded_one? && new_record? ? { _path => as_document } : {}
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/attributes/processing"
|
|
3
|
+
|
|
4
|
+
module Mongoid #:nodoc:
|
|
5
|
+
|
|
6
|
+
# This module contains the logic for handling the internal attributes hash,
|
|
7
|
+
# and how to get and set values.
|
|
8
|
+
module Attributes
|
|
9
|
+
include Processing
|
|
10
|
+
|
|
11
|
+
attr_reader :attributes
|
|
12
|
+
alias :raw_attributes :attributes
|
|
13
|
+
|
|
14
|
+
# Determine if an attribute is present.
|
|
15
|
+
#
|
|
16
|
+
# @example Is the attribute present?
|
|
17
|
+
# person.attribute_present?("title")
|
|
18
|
+
#
|
|
19
|
+
# @param [ String, Symbol ] name The name of the attribute.
|
|
20
|
+
#
|
|
21
|
+
# @return [ true, false ] True if present, false if not.
|
|
22
|
+
#
|
|
23
|
+
# @since 1.0.0
|
|
24
|
+
def attribute_present?(name)
|
|
25
|
+
!read_attribute(name).blank?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Read a value from the document attributes. If the value does not exist
|
|
29
|
+
# it will return nil.
|
|
30
|
+
#
|
|
31
|
+
# @example Read an attribute.
|
|
32
|
+
# person.read_attribute(:title)
|
|
33
|
+
#
|
|
34
|
+
# @example Read an attribute (alternate syntax.)
|
|
35
|
+
# person[:title]
|
|
36
|
+
#
|
|
37
|
+
# @param [ String, Symbol ] name The name of the attribute to get.
|
|
38
|
+
#
|
|
39
|
+
# @return [ Object ] The value of the attribute.
|
|
40
|
+
#
|
|
41
|
+
# @since 1.0.0
|
|
42
|
+
def read_attribute(name)
|
|
43
|
+
access = name.to_s
|
|
44
|
+
value = attributes[access]
|
|
45
|
+
accessed(access, value)
|
|
46
|
+
end
|
|
47
|
+
alias :[] :read_attribute
|
|
48
|
+
|
|
49
|
+
# Remove a value from the +Document+ attributes. If the value does not exist
|
|
50
|
+
# it will fail gracefully.
|
|
51
|
+
#
|
|
52
|
+
# @example Remove the attribute.
|
|
53
|
+
# person.remove_attribute(:title)
|
|
54
|
+
#
|
|
55
|
+
# @param [ String, Symbol ] name The name of the attribute to remove.
|
|
56
|
+
#
|
|
57
|
+
# @since 1.0.0
|
|
58
|
+
def remove_attribute(name)
|
|
59
|
+
access = name.to_s
|
|
60
|
+
modify(access, attributes.delete(access), nil)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Override respond_to? so it responds properly for dynamic attributes.
|
|
64
|
+
#
|
|
65
|
+
# @example Does this object respond to the method?
|
|
66
|
+
# person.respond_to?(:title)
|
|
67
|
+
#
|
|
68
|
+
# @param [ Array ] *args The name of the method.
|
|
69
|
+
#
|
|
70
|
+
# @return [ true, false ] True if it does, false if not.
|
|
71
|
+
#
|
|
72
|
+
# @since 1.0.0
|
|
73
|
+
def respond_to?(*args)
|
|
74
|
+
(Mongoid.allow_dynamic_fields &&
|
|
75
|
+
attributes &&
|
|
76
|
+
attributes.has_key?(args.first.to_s)
|
|
77
|
+
) || super
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Write a single attribute to the document attribute hash. This will
|
|
81
|
+
# also fire the before and after update callbacks, and perform any
|
|
82
|
+
# necessary typecasting.
|
|
83
|
+
#
|
|
84
|
+
# @example Write the attribute.
|
|
85
|
+
# person.write_attribute(:title, "Mr.")
|
|
86
|
+
#
|
|
87
|
+
# @example Write the attribute (alternate syntax.)
|
|
88
|
+
# person[:title] = "Mr."
|
|
89
|
+
#
|
|
90
|
+
# @param [ String, Symbol ] name The name of the attribute to update.
|
|
91
|
+
# @param [ Object ] value The value to set for the attribute.
|
|
92
|
+
#
|
|
93
|
+
# @since 1.0.0
|
|
94
|
+
def write_attribute(name, value)
|
|
95
|
+
access = name.to_s
|
|
96
|
+
modify(access, attributes[access], typed_value_for(access, value))
|
|
97
|
+
end
|
|
98
|
+
alias :[]= :write_attribute
|
|
99
|
+
|
|
100
|
+
# Writes the supplied attributes hash to the document. This will only
|
|
101
|
+
# overwrite existing attributes if they are present in the new +Hash+, all
|
|
102
|
+
# others will be preserved.
|
|
103
|
+
#
|
|
104
|
+
# @example Write the attributes.
|
|
105
|
+
# person.write_attributes(:title => "Mr.")
|
|
106
|
+
#
|
|
107
|
+
# @example Write the attributes (alternate syntax.)
|
|
108
|
+
# person.attributes = { :title => "Mr." }
|
|
109
|
+
#
|
|
110
|
+
# @param [ Hash ] attrs The new attributes to set.
|
|
111
|
+
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
|
112
|
+
#
|
|
113
|
+
# @since 1.0.0
|
|
114
|
+
def write_attributes(attrs = nil, guard_protected_attributes = true)
|
|
115
|
+
process(attrs, guard_protected_attributes) do |document|
|
|
116
|
+
document.identify if new? && id.blank?
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
alias :attributes= :write_attributes
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
# Get the default values for the attributes.
|
|
124
|
+
#
|
|
125
|
+
# @example Get the defaults.
|
|
126
|
+
# person.default_attributes
|
|
127
|
+
#
|
|
128
|
+
# @return [ Hash ] The default values for each field.
|
|
129
|
+
#
|
|
130
|
+
# @since 1.0.0
|
|
131
|
+
#
|
|
132
|
+
# @raise [ RuntimeError ] Always
|
|
133
|
+
# @since 2.0.0.rc.8
|
|
134
|
+
def default_attributes
|
|
135
|
+
raise "default_attributes is no longer valid. Plase use: apply_default_attributes."
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Set any missing default values in the attributes.
|
|
139
|
+
#
|
|
140
|
+
# @example Get the raw attributes after defaults have been applied.
|
|
141
|
+
# person.apply_default_attributes
|
|
142
|
+
#
|
|
143
|
+
# @return [ Hash ] The raw attributes.
|
|
144
|
+
#
|
|
145
|
+
# @since 2.0.0.rc.8
|
|
146
|
+
def apply_default_attributes
|
|
147
|
+
(@attributes ||= {}).tap do |h|
|
|
148
|
+
defaults.each_pair do |key, val|
|
|
149
|
+
unless h.has_key?(key)
|
|
150
|
+
h[key] = val.respond_to?(:call) ? typed_value_for(key, val.call) : val
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Used for allowing accessor methods for dynamic attributes.
|
|
157
|
+
#
|
|
158
|
+
# @param [ String, Symbol ] name The name of the method.
|
|
159
|
+
# @param [ Array ] *args The arguments to the method.
|
|
160
|
+
def method_missing(name, *args)
|
|
161
|
+
attr = name.to_s
|
|
162
|
+
return super unless attributes.has_key?(attr.reader)
|
|
163
|
+
if attr.writer?
|
|
164
|
+
write_attribute(attr.reader, (args.size > 1) ? args : args.first)
|
|
165
|
+
else
|
|
166
|
+
read_attribute(attr.reader)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Return the typecasted value for a field.
|
|
171
|
+
#
|
|
172
|
+
# @example Get the value typecasted.
|
|
173
|
+
# person.typed_value_for(:title, :sir)
|
|
174
|
+
#
|
|
175
|
+
# @param [ String, Symbol ] key The field name.
|
|
176
|
+
# @param [ Object ] value The uncast value.
|
|
177
|
+
#
|
|
178
|
+
# @return [ Object ] The cast value.
|
|
179
|
+
#
|
|
180
|
+
# @since 1.0.0
|
|
181
|
+
def typed_value_for(key, value)
|
|
182
|
+
fields.has_key?(key) ? fields[key].set(value) : value
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|