stonegao-mongoid 2.0.0.rc.6
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 +44 -0
- data/lib/config/locales/de.yml +44 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +44 -0
- data/lib/config/locales/fr.yml +45 -0
- data/lib/config/locales/hu.yml +47 -0
- data/lib/config/locales/it.yml +42 -0
- data/lib/config/locales/kr.yml +68 -0
- data/lib/config/locales/nl.yml +42 -0
- data/lib/config/locales/pl.yml +42 -0
- data/lib/config/locales/pt-br.yml +43 -0
- data/lib/config/locales/pt.yml +43 -0
- data/lib/config/locales/ro.yml +49 -0
- data/lib/config/locales/sv.yml +43 -0
- data/lib/config/locales/zh-CN.yml +34 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +251 -0
- data/lib/mongoid/callbacks.rb +13 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/collections.rb +70 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +48 -0
- data/lib/mongoid/config.rb +343 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/enumerable.rb +226 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/contexts.rb +21 -0
- data/lib/mongoid/copyable.rb +44 -0
- data/lib/mongoid/criteria.rb +325 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +67 -0
- data/lib/mongoid/criterion/inclusion.rb +134 -0
- data/lib/mongoid/criterion/inspection.rb +20 -0
- data/lib/mongoid/criterion/optional.rb +213 -0
- data/lib/mongoid/criterion/selector.rb +74 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/default_scope.rb +28 -0
- data/lib/mongoid/dirty.rb +251 -0
- data/lib/mongoid/document.rb +256 -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/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/errors.rb +12 -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/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 +57 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -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/extensions.rb +116 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +95 -0
- data/lib/mongoid/fields.rb +138 -0
- data/lib/mongoid/finders.rb +173 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +89 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +58 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +77 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +27 -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/size.rb +11 -0
- data/lib/mongoid/matchers.rb +55 -0
- data/lib/mongoid/modifiers/command.rb +18 -0
- data/lib/mongoid/modifiers/inc.rb +24 -0
- data/lib/mongoid/modifiers.rb +24 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +80 -0
- data/lib/mongoid/named_scope.rb +36 -0
- data/lib/mongoid/nested_attributes.rb +43 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence/command.rb +59 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +42 -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 +76 -0
- data/lib/mongoid/persistence.rb +237 -0
- data/lib/mongoid/railtie.rb +129 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations/accessors.rb +157 -0
- data/lib/mongoid/relations/auto_save.rb +34 -0
- data/lib/mongoid/relations/binding.rb +26 -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 +99 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/builder.rb +42 -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 +116 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
- data/lib/mongoid/relations/builders.rb +79 -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/cascading.rb +55 -0
- data/lib/mongoid/relations/constraint.rb +45 -0
- data/lib/mongoid/relations/cyclic.rb +97 -0
- data/lib/mongoid/relations/embedded/in.rb +173 -0
- data/lib/mongoid/relations/embedded/many.rb +483 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +306 -0
- data/lib/mongoid/relations/many.rb +171 -0
- data/lib/mongoid/relations/metadata.rb +533 -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 +128 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +443 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +344 -0
- data/lib/mongoid/relations/referenced/one.rb +206 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/relations.rb +105 -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/state.rb +66 -0
- data/lib/mongoid/timestamps.rb +38 -0
- data/lib/mongoid/validations/associated.rb +42 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/validations.rb +117 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +51 -0
- data/lib/mongoid.rb +139 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +23 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +17 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/lib/rails/mongoid.rb +57 -0
- metadata +380 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
pt:
|
|
2
|
+
activemodel:
|
|
3
|
+
errors:
|
|
4
|
+
messages:
|
|
5
|
+
taken: já está utilizada
|
|
6
|
+
|
|
7
|
+
mongoid:
|
|
8
|
+
errors:
|
|
9
|
+
messages:
|
|
10
|
+
document_not_found:
|
|
11
|
+
Nenhum documento encontrado para a classe %{klass} com os id(s) %{identifiers}.
|
|
12
|
+
invalid_database:
|
|
13
|
+
A base de dados deverá ser uma Mongo::DB, em vez de %{name}.
|
|
14
|
+
invalid_type:
|
|
15
|
+
O campo foi definido como %{klass}, mas recebeu uma instância de %{other} com
|
|
16
|
+
o valor %{value}.
|
|
17
|
+
unsupported_version:
|
|
18
|
+
MongoDB %{version} não é suportada, por favor actualize para a
|
|
19
|
+
versão %{mongo_version}.
|
|
20
|
+
validations:
|
|
21
|
+
A validação falhou - %{errors}.
|
|
22
|
+
invalid_collection:
|
|
23
|
+
O acesso à colecção para %{klass} não é permitido porque
|
|
24
|
+
é um documento embebido, por favor aceda à colecção através
|
|
25
|
+
do documento raiz.
|
|
26
|
+
invalid_field:
|
|
27
|
+
Não é permitido definir um campo com o nome %{name}. Não defina
|
|
28
|
+
campos que entrem em conflito com os nomes dos atributos internos e métodos
|
|
29
|
+
do Mongoid. Use Document#instance_methods para consultar esses nomes.
|
|
30
|
+
too_many_nested_attribute_records:
|
|
31
|
+
A aceitação de atributos encadeados para %{association} encontra-se limitada
|
|
32
|
+
a %{limit} registros.
|
|
33
|
+
embedded_in_must_have_inverse_of:
|
|
34
|
+
As opções para uma associação embedded_in devem incluir inverse_of.
|
|
35
|
+
dependent_only_references_one_or_many:
|
|
36
|
+
A opção The dependent => destroy|delete que é fornecida
|
|
37
|
+
é apenas válida para associações references_one ou references_many.
|
|
38
|
+
association_cant_have_inverse_of:
|
|
39
|
+
A definição de inverse_of nesta associação não é permitida. Apenas
|
|
40
|
+
use esta opção em embedded_in ou references_many como lista.
|
|
41
|
+
unsaved_document:
|
|
42
|
+
You cannot call create or create! through a relational association
|
|
43
|
+
relation (%{document}) who's parent (%{base}) is not already saved.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
ro:
|
|
2
|
+
activemodel:
|
|
3
|
+
errors:
|
|
4
|
+
messages:
|
|
5
|
+
taken: este deja folosit
|
|
6
|
+
|
|
7
|
+
mongoid:
|
|
8
|
+
errors:
|
|
9
|
+
messages:
|
|
10
|
+
document_not_found:
|
|
11
|
+
Nu există document în clasa %{klass} cu id %{identifiers}.
|
|
12
|
+
invalid_database:
|
|
13
|
+
Baza de date ar trebui să fie de tipul Mongo::DB, nu %{name}.
|
|
14
|
+
invalid_type:
|
|
15
|
+
Câmpul a fost definit ca şi un(o) %{klass}, dar valoarea
|
|
16
|
+
recepţionată %{value} este de clasa %{other}.
|
|
17
|
+
unsupported_version:
|
|
18
|
+
Versiunea MongoDB %{version} nu este suportată.
|
|
19
|
+
Vă rugăm să folosiţi versiunea %{mongo_version}.
|
|
20
|
+
validations:
|
|
21
|
+
Validare nereuşită - %{errors}.
|
|
22
|
+
invalid_collection:
|
|
23
|
+
Accesul la colecţie din clasa %{klass} este interzisă, fiindcă
|
|
24
|
+
este un document încorporat. Vă rugăm accesaţi colecţia din
|
|
25
|
+
documentul rădăcină.
|
|
26
|
+
invalid_field:
|
|
27
|
+
Folosirea denumirii %{name} ptr. un câmp este interzisă. Vă
|
|
28
|
+
rugăm să evitaţi utilizarea acelor cuvinte care intră în conflict
|
|
29
|
+
cu denumirile folosite de proprietăţile sau metodele Mongoid-lui.
|
|
30
|
+
Folosiţi comanda Document#instance_methods pentru a afla care
|
|
31
|
+
sunt acestea.
|
|
32
|
+
too_many_nested_attribute_records:
|
|
33
|
+
În cazul %{association} folosirea atributelor îmbricate este
|
|
34
|
+
limitat la %{limit} înregistrări.
|
|
35
|
+
embedded_in_must_have_inverse_of:
|
|
36
|
+
Folosirea opţiunii inverse_of este obligatorie în cazul
|
|
37
|
+
asociaţiilor de tip embedded_in.
|
|
38
|
+
dependent_only_references_one_or_many:
|
|
39
|
+
Opţiunea dependent => destroy|delete poate fi folosită doar în
|
|
40
|
+
cazul asociaţiilor de tip references_one sau references_many.
|
|
41
|
+
association_cant_have_inverse_of:
|
|
42
|
+
Folosire opţiunii inverse_of la acest tip de asociaţie este
|
|
43
|
+
interzisă. Aceasta poate fi folosită doar la asociaţiile de
|
|
44
|
+
tip embedded_in sau references_many as array.
|
|
45
|
+
calling_document_find_with_nil_is_invalid:
|
|
46
|
+
Folosirea metodei Document#find cu valoarea nil este invalidă.
|
|
47
|
+
unsaved_document:
|
|
48
|
+
You cannot call create or create! through a relational association
|
|
49
|
+
relation (%{document}) who's parent (%{base}) is not already saved.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
sv:
|
|
2
|
+
activemodel:
|
|
3
|
+
errors:
|
|
4
|
+
messages:
|
|
5
|
+
taken: har redan använts
|
|
6
|
+
|
|
7
|
+
mongoid:
|
|
8
|
+
errors:
|
|
9
|
+
messages:
|
|
10
|
+
document_not_found:
|
|
11
|
+
Inget dokument kunde hittas för klass %{klass} med id %{identifiers}.
|
|
12
|
+
invalid_database:
|
|
13
|
+
Databasen bör vara Mongo::DB, inte %{name}.
|
|
14
|
+
invalid_type:
|
|
15
|
+
Fältet var definerat som %{klass}, men fick %{other} med
|
|
16
|
+
värdet %{value}.
|
|
17
|
+
unsupported_version:
|
|
18
|
+
MongoDB %{version} stöds ej, vänligen upgradera
|
|
19
|
+
till %{mongo_version}.
|
|
20
|
+
validations:
|
|
21
|
+
Validering misslyckades - %{errors}.
|
|
22
|
+
invalid_collection:
|
|
23
|
+
Tillgång till kollektionen för %{klass} är inte tillåten eftersom den
|
|
24
|
+
är ett inbäddat dokument, vänligen accessa kollektionen från
|
|
25
|
+
rotdokumentet.
|
|
26
|
+
invalid_field:
|
|
27
|
+
Att definera ett fält med namnet %{name} är inte tillåtet. Definera inte
|
|
28
|
+
fält som är i konflikt med Mongoids interna attribut eller metod
|
|
29
|
+
namn. Använd Document#instance_methods för att se vilka namn detta innefattar.
|
|
30
|
+
too_many_nested_attribute_records:
|
|
31
|
+
Acceptans av nästlade attribut för %{association} är begränsat
|
|
32
|
+
till %{limit} register.
|
|
33
|
+
embedded_in_must_have_inverse_of:
|
|
34
|
+
Alternativ för en embedded_in association måste innehålla inverse_of.
|
|
35
|
+
dependent_only_references_one_or_many:
|
|
36
|
+
Alternativet dependent => destroy|delete som angavs
|
|
37
|
+
är endast giltigt för references_one eller references_many associationer.
|
|
38
|
+
association_cant_have_inverse_of:
|
|
39
|
+
Att definera inverse_of på denna association är inte tillåtet. Använd
|
|
40
|
+
endast detta alternativ på embedded_in eller references_many as array.
|
|
41
|
+
unsaved_document:
|
|
42
|
+
You cannot call create or create! through a relational association
|
|
43
|
+
relation (%{document}) who's parent (%{base}) is not already saved.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
en:
|
|
2
|
+
activemodel:
|
|
3
|
+
errors:
|
|
4
|
+
messages:
|
|
5
|
+
taken: 已占用
|
|
6
|
+
|
|
7
|
+
mongoid:
|
|
8
|
+
errors:
|
|
9
|
+
messages:
|
|
10
|
+
document_not_found:
|
|
11
|
+
没有发现类是%{klass}id(s)是%{identifiers}的文档
|
|
12
|
+
invalid_database:
|
|
13
|
+
数据库应该是Mongo::DB,而不是%{name}.
|
|
14
|
+
invalid_type:
|
|
15
|
+
在类%{klass}中定义了字段,实际值是%{value}的%{other}.
|
|
16
|
+
unsupported_version:
|
|
17
|
+
MongoDB %{version} 版本已过期,请升级到 %{mongo_version}.
|
|
18
|
+
validations:
|
|
19
|
+
校验失败 - %{errors}.
|
|
20
|
+
invalid_collection:
|
|
21
|
+
不允许直接访问嵌入式的集合%{klass} , 请从文档的根访问集合.
|
|
22
|
+
invalid_field:
|
|
23
|
+
字段的名字不允许为 %{name}. 你不应该定义跟Mongoid内部属性或者方法相同的名字,详细请看Use Document#instance_methods.
|
|
24
|
+
too_many_nested_attribute_records:
|
|
25
|
+
被关联的%{association} 嵌入式属性不能超过 %{limit}.
|
|
26
|
+
embedded_in_must_have_inverse_of:
|
|
27
|
+
embedded_in的关联属性必须包含inverse_of.
|
|
28
|
+
dependent_only_references_one_or_many:
|
|
29
|
+
dependent => destroy|delete 选项只有在references_one或者references_many时候有效.
|
|
30
|
+
association_cant_have_inverse_of:
|
|
31
|
+
在当前的关联中,不允许定义inverse_of去,其只有在embedded_in或者references_many是数组的情况下使用
|
|
32
|
+
unsaved_document:
|
|
33
|
+
You cannot call create or create! through a relational association
|
|
34
|
+
relation (%{document}) who's parent (%{base}) is not already saved.
|
|
@@ -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._conficting_modification_key] = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if processed.has_key?(child._conficting_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 _conficting_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 => to_hash } : {}
|
|
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 => to_hash } : {}
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
|
|
4
|
+
# This module contains the logic for handling the internal attributes hash,
|
|
5
|
+
# and how to get and set values.
|
|
6
|
+
module Attributes
|
|
7
|
+
|
|
8
|
+
# Returns the object type. This corresponds to the name of the class that
|
|
9
|
+
# this document is, which is used in determining the class to
|
|
10
|
+
# instantiate in various cases.
|
|
11
|
+
#
|
|
12
|
+
# @example Get the type.
|
|
13
|
+
# person._type
|
|
14
|
+
#
|
|
15
|
+
# @return [ String ] The name of the class the document is.
|
|
16
|
+
def _type
|
|
17
|
+
@attributes["_type"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Set the type of the document. This should be the name of the class.
|
|
21
|
+
#
|
|
22
|
+
# @example Set the type
|
|
23
|
+
# person._type = "Person"
|
|
24
|
+
#
|
|
25
|
+
# @param [ String ] new_type The name of the class.
|
|
26
|
+
#
|
|
27
|
+
# @return [ String ] the new type.
|
|
28
|
+
def _type=(new_type)
|
|
29
|
+
@attributes["_type"] = new_type
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Determine if an attribute is present.
|
|
33
|
+
#
|
|
34
|
+
# @example Is the attribute present?
|
|
35
|
+
# person.attribute_present?("title")
|
|
36
|
+
#
|
|
37
|
+
# @param [ String, Symbol ] name The name of the attribute.
|
|
38
|
+
#
|
|
39
|
+
# @return [ true, false ] True if present, false if not.
|
|
40
|
+
def attribute_present?(name)
|
|
41
|
+
!read_attribute(name).blank?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get the id associated with this object. This will pull the _id value out
|
|
45
|
+
# of the attributes.
|
|
46
|
+
#
|
|
47
|
+
# @example Get the id.
|
|
48
|
+
# person.id
|
|
49
|
+
#
|
|
50
|
+
# @return [ BSON::ObjectId, String ] The id of the document.
|
|
51
|
+
def id
|
|
52
|
+
@attributes["_id"]
|
|
53
|
+
end
|
|
54
|
+
alias :_id :id
|
|
55
|
+
|
|
56
|
+
# Set the id of the document to a new one.
|
|
57
|
+
#
|
|
58
|
+
# @example Set the id.
|
|
59
|
+
# person.id = BSON::ObjectId.new
|
|
60
|
+
#
|
|
61
|
+
# @param [ BSON::ObjectId, String ] new_id The new id.
|
|
62
|
+
#
|
|
63
|
+
# @return [ BSON::ObjectId, String ] The new id.
|
|
64
|
+
def id=(new_id)
|
|
65
|
+
@attributes["_id"] = _id_type.set(new_id)
|
|
66
|
+
end
|
|
67
|
+
alias :_id= :id=
|
|
68
|
+
|
|
69
|
+
# Used for allowing accessor methods for dynamic attributes.
|
|
70
|
+
#
|
|
71
|
+
# @param [ String, Symbol ] name The name of the method.
|
|
72
|
+
# @param [ Array ] *args The arguments to the method.
|
|
73
|
+
def method_missing(name, *args)
|
|
74
|
+
attr = name.to_s
|
|
75
|
+
return super unless @attributes.has_key?(attr.reader)
|
|
76
|
+
if attr.writer?
|
|
77
|
+
# "args.size > 1" allows to simulate 1.8 behavior of "*args"
|
|
78
|
+
write_attribute(attr.reader, (args.size > 1) ? args : args.first)
|
|
79
|
+
else
|
|
80
|
+
read_attribute(attr.reader)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Process the provided attributes casting them to their proper values if a
|
|
85
|
+
# field exists for them on the document. This will be limited to only the
|
|
86
|
+
# attributes provided in the suppied +Hash+ so that no extra nil values get
|
|
87
|
+
# put into the document's attributes.
|
|
88
|
+
#
|
|
89
|
+
# @example Process the attributes.
|
|
90
|
+
# person.process(:title => "sir", :age => 40)
|
|
91
|
+
#
|
|
92
|
+
# @param [ Hash ] attrs The attributes to set.
|
|
93
|
+
def process(attrs = nil)
|
|
94
|
+
pending = {}
|
|
95
|
+
sanitize_for_mass_assignment(attrs || {}).each_pair do |key, value|
|
|
96
|
+
if set_allowed?(key)
|
|
97
|
+
write_attribute(key, value)
|
|
98
|
+
else
|
|
99
|
+
pending[key.to_s] = value and next if relations.has_key?(key.to_s)
|
|
100
|
+
send("#{key}=", value)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
yield self if block_given?
|
|
104
|
+
process_relations(pending)
|
|
105
|
+
setup_modifications
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Read a value from the document attributes. If the value does not exist
|
|
109
|
+
# it will return nil.
|
|
110
|
+
#
|
|
111
|
+
# @example Read an attribute.
|
|
112
|
+
# person.read_attribute(:title)
|
|
113
|
+
#
|
|
114
|
+
# @example Read an attribute (alternate syntax.)
|
|
115
|
+
# person[:title]
|
|
116
|
+
#
|
|
117
|
+
# @param [ String, Symbol ] name The name of the attribute to get.
|
|
118
|
+
#
|
|
119
|
+
# @return [ Object ] The value of the attribute.
|
|
120
|
+
def read_attribute(name)
|
|
121
|
+
access = name.to_s
|
|
122
|
+
value = @attributes[access]
|
|
123
|
+
typed_value = fields.has_key?(access) ? fields[access].get(value) : value
|
|
124
|
+
accessed(access, typed_value)
|
|
125
|
+
end
|
|
126
|
+
alias :[] :read_attribute
|
|
127
|
+
|
|
128
|
+
# Remove a value from the +Document+ attributes. If the value does not exist
|
|
129
|
+
# it will fail gracefully.
|
|
130
|
+
#
|
|
131
|
+
# @example Remove the attribute.
|
|
132
|
+
# person.remove_attribute(:title)
|
|
133
|
+
#
|
|
134
|
+
# @param [ String, Symbol ] name The name of the attribute to remove.
|
|
135
|
+
def remove_attribute(name)
|
|
136
|
+
access = name.to_s
|
|
137
|
+
modify(access, @attributes.delete(name.to_s), nil)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Override respond_to? so it responds properly for dynamic attributes.
|
|
141
|
+
#
|
|
142
|
+
# @example Does this object respond to the method?
|
|
143
|
+
# person.respond_to?(:title)
|
|
144
|
+
#
|
|
145
|
+
# @param [ Array ] *args The name of the method.
|
|
146
|
+
#
|
|
147
|
+
# @return [ true, false ] True if it does, false if not.
|
|
148
|
+
def respond_to?(*args)
|
|
149
|
+
(Mongoid.allow_dynamic_fields &&
|
|
150
|
+
@attributes &&
|
|
151
|
+
@attributes.has_key?(args.first.to_s)
|
|
152
|
+
) || super
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Write a single attribute to the document attribute hash. This will
|
|
156
|
+
# also fire the before and after update callbacks, and perform any
|
|
157
|
+
# necessary typecasting.
|
|
158
|
+
#
|
|
159
|
+
# @example Write the attribute.
|
|
160
|
+
# person.write_attribute(:title, "Mr.")
|
|
161
|
+
#
|
|
162
|
+
# @example Write the attribute (alternate syntax.)
|
|
163
|
+
# person[:title] = "Mr."
|
|
164
|
+
#
|
|
165
|
+
# @param [ String, Symbol ] name The name of the attribute to update.
|
|
166
|
+
# @param [ Object ] value The value to set for the attribute.
|
|
167
|
+
def write_attribute(name, value)
|
|
168
|
+
access = name.to_s
|
|
169
|
+
modify(access, @attributes[access], typed_value_for(access, value))
|
|
170
|
+
end
|
|
171
|
+
alias :[]= :write_attribute
|
|
172
|
+
|
|
173
|
+
# Writes the supplied attributes hash to the document. This will only
|
|
174
|
+
# overwrite existing attributes if they are present in the new +Hash+, all
|
|
175
|
+
# others will be preserved.
|
|
176
|
+
#
|
|
177
|
+
# @example Write the attributes.
|
|
178
|
+
# person.write_attributes(:title => "Mr.")
|
|
179
|
+
#
|
|
180
|
+
# @example Write the attributes (alternate syntax.)
|
|
181
|
+
# person.attributes = { :title => "Mr." }
|
|
182
|
+
#
|
|
183
|
+
# @param [ Hash ] attrs The new attributes to set.
|
|
184
|
+
def write_attributes(attrs = nil)
|
|
185
|
+
process(attrs || {})
|
|
186
|
+
if new_record? && id.blank?
|
|
187
|
+
identify
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
alias :attributes= :write_attributes
|
|
191
|
+
|
|
192
|
+
protected
|
|
193
|
+
|
|
194
|
+
# Get the default values for the attributes.
|
|
195
|
+
#
|
|
196
|
+
# @example Get the defaults.
|
|
197
|
+
# person.default_attributes
|
|
198
|
+
#
|
|
199
|
+
# @return [ Hash ] The default values for each field.
|
|
200
|
+
def default_attributes
|
|
201
|
+
default_values = defaults
|
|
202
|
+
default_values.each_pair do |key, val|
|
|
203
|
+
default_values[key] = typed_value_for(key, val.call) if val.respond_to?(:call)
|
|
204
|
+
end
|
|
205
|
+
default_values || {}
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Process all the pending relations that needed to wait until ids were set
|
|
209
|
+
# to fire off.
|
|
210
|
+
#
|
|
211
|
+
# @example Process the relations.
|
|
212
|
+
# document.process_relations({ "addressable" => person })
|
|
213
|
+
#
|
|
214
|
+
# @param [ Hash ] pending The pending relation values.
|
|
215
|
+
def process_relations(pending)
|
|
216
|
+
pending.each_pair do |name, value|
|
|
217
|
+
metadata = relations[name]
|
|
218
|
+
if value.is_a?(Hash)
|
|
219
|
+
metadata.nested_builder(value, {}).build(self)
|
|
220
|
+
else
|
|
221
|
+
send("#{name}=", value, :binding => true)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Return true if dynamic field setting is enabled.
|
|
227
|
+
#
|
|
228
|
+
# @example Is a set allowed for this name?
|
|
229
|
+
# person.set_allowed?(:title)
|
|
230
|
+
#
|
|
231
|
+
# @param [ String, Symbol ] key The name of the field.
|
|
232
|
+
#
|
|
233
|
+
# @return [ true, false ] True if allowed, false if not.
|
|
234
|
+
def set_allowed?(key)
|
|
235
|
+
Mongoid.allow_dynamic_fields && !respond_to?("#{key}=")
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Return the typecasted value for a field.
|
|
239
|
+
#
|
|
240
|
+
# @example Get the value typecasted.
|
|
241
|
+
# person.typed_value_for(:title, :sir)
|
|
242
|
+
#
|
|
243
|
+
# @param [ String, Symbol ] key The field name.
|
|
244
|
+
# @param [ Object ] value The uncast value.
|
|
245
|
+
#
|
|
246
|
+
# @return [ Object ] The cast value.
|
|
247
|
+
def typed_value_for(key, value)
|
|
248
|
+
fields.has_key?(key) ? fields[key].set(value) : value
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Callbacks
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
extend ActiveModel::Callbacks
|
|
7
|
+
include ActiveModel::Validations::Callbacks
|
|
8
|
+
|
|
9
|
+
define_model_callbacks :initialize, :only => :after
|
|
10
|
+
define_model_callbacks :create, :destroy, :save, :update
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/collections/operations"
|
|
3
|
+
require "mongoid/collections/cyclic_iterator"
|
|
4
|
+
require "mongoid/collections/master"
|
|
5
|
+
require "mongoid/collections/slaves"
|
|
6
|
+
|
|
7
|
+
module Mongoid #:nodoc
|
|
8
|
+
|
|
9
|
+
# This class is the Mongoid wrapper to the Mongo Ruby driver's collection
|
|
10
|
+
# object.
|
|
11
|
+
class Collection
|
|
12
|
+
attr_reader :counter, :name
|
|
13
|
+
|
|
14
|
+
# All write operations should delegate to the master connection. These
|
|
15
|
+
# operations mimic the methods on a Mongo:Collection.
|
|
16
|
+
#
|
|
17
|
+
# @example Delegate the operation.
|
|
18
|
+
# collection.save({ :name => "Al" })
|
|
19
|
+
Collections::Operations::PROXIED.each do |name|
|
|
20
|
+
define_method(name) { |*args| master.send(name, *args) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Determines where to send the next read query. If the slaves are not
|
|
24
|
+
# defined then send to master. If the read counter is under the configured
|
|
25
|
+
# maximum then return the master. In any other case return the slaves.
|
|
26
|
+
#
|
|
27
|
+
# @example Send the operation to the master or slaves.
|
|
28
|
+
# collection.directed
|
|
29
|
+
#
|
|
30
|
+
# @param [ Hash ] options The operation options.
|
|
31
|
+
#
|
|
32
|
+
# @option options [ true, false ] :cache Should the query cache in memory?
|
|
33
|
+
# @option options [ true, false ] :enslave Send the write to the slave?
|
|
34
|
+
#
|
|
35
|
+
# @return [ Master, Slaves ] The connection to use.
|
|
36
|
+
def directed(options = {})
|
|
37
|
+
options.delete(:cache)
|
|
38
|
+
enslave = options.delete(:enslave) || @klass.enslaved?
|
|
39
|
+
enslave ? master_or_slaves : master
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Find documents from the database given a selector and options.
|
|
43
|
+
#
|
|
44
|
+
# @example Find documents in the collection.
|
|
45
|
+
# collection.find({ :test => "value" })
|
|
46
|
+
#
|
|
47
|
+
# @param [ Hash ] selector The query selector.
|
|
48
|
+
# @param [ Hash ] options The options to pass to the db.
|
|
49
|
+
#
|
|
50
|
+
# @return [ Cursor ] The results.
|
|
51
|
+
def find(selector = {}, options = {})
|
|
52
|
+
cursor = Mongoid::Cursor.new(@klass, self, directed(options).find(selector, options))
|
|
53
|
+
if block_given?
|
|
54
|
+
yield cursor; cursor.close
|
|
55
|
+
else
|
|
56
|
+
cursor
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Find the first document from the database given a selector and options.
|
|
61
|
+
#
|
|
62
|
+
# @example Find one document.
|
|
63
|
+
# collection.find_one({ :test => "value" })
|
|
64
|
+
#
|
|
65
|
+
# @param [ Hash ] selector The query selector.
|
|
66
|
+
# @param [ Hash ] options The options to pass to the db.
|
|
67
|
+
#
|
|
68
|
+
# @return [ Document, nil ] A matching document or nil if none found.
|
|
69
|
+
def find_one(selector = {}, options = {})
|
|
70
|
+
directed(options).find_one(selector, options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Initialize a new Mongoid::Collection, setting up the master, slave, and
|
|
74
|
+
# name attributes. Masters will be used for writes, slaves for reads.
|
|
75
|
+
#
|
|
76
|
+
# @example Create the new collection.
|
|
77
|
+
# Collection.new(masters, slaves, "test")
|
|
78
|
+
#
|
|
79
|
+
# @param [ Class ] klass The class the collection is for.
|
|
80
|
+
# @param [ String ] name The name of the collection.
|
|
81
|
+
def initialize(klass, name)
|
|
82
|
+
@klass, @name = klass, name
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Perform a map/reduce on the documents.
|
|
86
|
+
#
|
|
87
|
+
# @example Perform the map/reduce.
|
|
88
|
+
# collection.map_reduce(map, reduce)
|
|
89
|
+
#
|
|
90
|
+
# @param [ String ] map The map javascript function.
|
|
91
|
+
# @param [ String ] reduce The reduce javascript function.
|
|
92
|
+
# @param [ Hash ] options The options to pass to the db.
|
|
93
|
+
#
|
|
94
|
+
# @return [ Cursor ] The results.
|
|
95
|
+
def map_reduce(map, reduce, options = {})
|
|
96
|
+
directed(options).map_reduce(map, reduce, options)
|
|
97
|
+
end
|
|
98
|
+
alias :mapreduce :map_reduce
|
|
99
|
+
|
|
100
|
+
# Return the object responsible for writes to the database. This will
|
|
101
|
+
# always return a collection associated with the Master DB.
|
|
102
|
+
#
|
|
103
|
+
# @example Get the master connection.
|
|
104
|
+
# collection.master
|
|
105
|
+
#
|
|
106
|
+
# @return [ Master ] The master connection.
|
|
107
|
+
def master
|
|
108
|
+
db = Mongoid.databases[@klass.database] || Mongoid.master
|
|
109
|
+
@master ||= Collections::Master.new(db, @name)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Return the object responsible for reading documents from the database.
|
|
113
|
+
# This is usually the slave databases, but in their absence the master will
|
|
114
|
+
# handle the task.
|
|
115
|
+
#
|
|
116
|
+
# @example Get the slaves array.
|
|
117
|
+
# collection.slaves
|
|
118
|
+
#
|
|
119
|
+
# @return [ Slaves ] The pool of slave connections.
|
|
120
|
+
def slaves
|
|
121
|
+
slaves = Mongoid.databases["#{@klass.database}_slaves"] || Mongoid.slaves
|
|
122
|
+
@slaves ||= Collections::Slaves.new(slaves, @name)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
protected
|
|
126
|
+
|
|
127
|
+
# Determine if the read is going to the master or the slaves.
|
|
128
|
+
#
|
|
129
|
+
# @example Use the master or slaves?
|
|
130
|
+
# collection.master_or_slaves
|
|
131
|
+
#
|
|
132
|
+
# @return [ Master, Slaves ] Master if not slaves exist, or slaves.
|
|
133
|
+
def master_or_slaves
|
|
134
|
+
slaves.empty? ? master : slaves
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|