mongoid 9.1.0 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/lib/config/locales/en.yml +49 -0
  3. data/lib/mongoid/association/accessors.rb +9 -1
  4. data/lib/mongoid/association/depending.rb +14 -10
  5. data/lib/mongoid/association/eager.rb +9 -0
  6. data/lib/mongoid/association/eager_load/discriminated_inclusion.rb +88 -0
  7. data/lib/mongoid/association/eager_load/embedded_distributor.rb +151 -0
  8. data/lib/mongoid/association/eager_load/inclusion.rb +173 -0
  9. data/lib/mongoid/association/eager_load/inclusion_tree.rb +96 -0
  10. data/lib/mongoid/association/eager_load/lookup_pipeline.rb +121 -0
  11. data/lib/mongoid/association/eager_load/polymorphic_preloader.rb +61 -0
  12. data/lib/mongoid/association/eager_load/polymorphic_targets.rb +151 -0
  13. data/lib/mongoid/association/eager_loadable.rb +57 -100
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -1
  15. data/lib/mongoid/association/embedded/embeds_one.rb +1 -0
  16. data/lib/mongoid/association/macros.rb +13 -1
  17. data/lib/mongoid/association/nested/many.rb +34 -5
  18. data/lib/mongoid/association/nested/nested_buildable.rb +14 -0
  19. data/lib/mongoid/association/nested/one.rb +6 -1
  20. data/lib/mongoid/association/options.rb +17 -0
  21. data/lib/mongoid/association/referenced/belongs_to/eager.rb +6 -1
  22. data/lib/mongoid/association/referenced/belongs_to.rb +1 -0
  23. data/lib/mongoid/association/referenced/counter_cache.rb +3 -3
  24. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +5 -0
  25. data/lib/mongoid/association/referenced/has_many/enumerable.rb +3 -1
  26. data/lib/mongoid/association/referenced/has_many/proxy.rb +100 -1
  27. data/lib/mongoid/association/referenced/has_many_through/eager.rb +99 -0
  28. data/lib/mongoid/association/referenced/has_many_through/proxy.rb +68 -0
  29. data/lib/mongoid/association/referenced/has_many_through.rb +201 -0
  30. data/lib/mongoid/association/referenced/has_one.rb +1 -0
  31. data/lib/mongoid/association/referenced/has_one_through/eager.rb +65 -0
  32. data/lib/mongoid/association/referenced/has_one_through/proxy.rb +30 -0
  33. data/lib/mongoid/association/referenced/has_one_through.rb +167 -0
  34. data/lib/mongoid/association/referenced.rb +2 -0
  35. data/lib/mongoid/association/relatable.rb +40 -0
  36. data/lib/mongoid/association.rb +7 -0
  37. data/lib/mongoid/clients/factory.rb +7 -13
  38. data/lib/mongoid/collection_configurable.rb +8 -0
  39. data/lib/mongoid/config/defaults.rb +0 -1
  40. data/lib/mongoid/config/encryption.rb +36 -19
  41. data/lib/mongoid/config.rb +56 -5
  42. data/lib/mongoid/contextual/aggregable/memory.rb +6 -2
  43. data/lib/mongoid/contextual/memory.rb +18 -7
  44. data/lib/mongoid/criteria/includable.rb +35 -11
  45. data/lib/mongoid/criteria/queryable/mergeable.rb +4 -0
  46. data/lib/mongoid/criteria/queryable/selectable.rb +123 -7
  47. data/lib/mongoid/deprecable.rb +45 -2
  48. data/lib/mongoid/encryptable.rb +46 -0
  49. data/lib/mongoid/errors/config_redactor.rb +43 -0
  50. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +26 -0
  51. data/lib/mongoid/errors/mixed_client_configuration.rb +1 -1
  52. data/lib/mongoid/errors/no_client_database.rb +1 -1
  53. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  54. data/lib/mongoid/errors/no_encryption_schema.rb +28 -0
  55. data/lib/mongoid/errors/readonly_association.rb +29 -0
  56. data/lib/mongoid/errors.rb +4 -0
  57. data/lib/mongoid/extensions/vector.rb +64 -0
  58. data/lib/mongoid/extensions.rb +1 -0
  59. data/lib/mongoid/field_readable.rb +69 -0
  60. data/lib/mongoid/indexable.rb +38 -26
  61. data/lib/mongoid/matchable.rb +6 -1
  62. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +2 -4
  63. data/lib/mongoid/matcher/regex.rb +11 -12
  64. data/lib/mongoid/matcher/regexp_budget.rb +372 -0
  65. data/lib/mongoid/matcher.rb +1 -0
  66. data/lib/mongoid/persistable/creatable.rb +1 -1
  67. data/lib/mongoid/persistable/updatable.rb +9 -11
  68. data/lib/mongoid/persistence_context.rb +35 -0
  69. data/lib/mongoid/search_indexable.rb +64 -23
  70. data/lib/mongoid/serializable.rb +12 -4
  71. data/lib/mongoid/tasks/database.rb +23 -9
  72. data/lib/mongoid/threaded.rb +36 -0
  73. data/lib/mongoid/timestamps/timeless.rb +84 -10
  74. data/lib/mongoid/traversable.rb +2 -2
  75. data/lib/mongoid/validatable/associated.rb +18 -2
  76. data/lib/mongoid/version.rb +1 -1
  77. data/spec/integration/app_spec.rb +7 -1
  78. data/spec/integration/associations/belongs_to_spec.rb +13 -0
  79. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +17 -2
  80. data/spec/integration/dots_and_dollars_spec.rb +12 -2
  81. data/spec/integration/encryption_spec.rb +151 -0
  82. data/spec/integration/matcher_operator_data/regex.yml +21 -0
  83. data/spec/integration/matcher_regexp_timeout_spec.rb +215 -0
  84. data/spec/integration/query_operator_guard_spec.rb +89 -0
  85. data/spec/mongoid/association/eager_loadable_spec.rb +47 -0
  86. data/spec/mongoid/association/eager_spec.rb +2 -2
  87. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +33 -0
  88. data/spec/mongoid/association/fallback_spec.rb +425 -0
  89. data/spec/mongoid/association/macros_spec.rb +26 -0
  90. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +17 -0
  91. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +48 -0
  92. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +50 -0
  93. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +33 -0
  94. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +145 -0
  95. data/spec/mongoid/association/referenced/has_many_through/eager_spec.rb +58 -0
  96. data/spec/mongoid/association/referenced/has_many_through/proxy_spec.rb +62 -0
  97. data/spec/mongoid/association/referenced/has_many_through_spec.rb +399 -0
  98. data/spec/mongoid/association/referenced/has_one_through/eager_spec.rb +58 -0
  99. data/spec/mongoid/association/referenced/has_one_through/proxy_spec.rb +49 -0
  100. data/spec/mongoid/association/referenced/has_one_through_spec.rb +211 -0
  101. data/spec/mongoid/attributes/nested_spec.rb +249 -8
  102. data/spec/mongoid/config/defaults_spec.rb +33 -0
  103. data/spec/mongoid/config/encryption_spec.rb +228 -0
  104. data/spec/mongoid/contextual/aggregable/memory_spec.rb +91 -0
  105. data/spec/mongoid/contextual/memory_spec.rb +177 -0
  106. data/spec/mongoid/criteria/includable_spec.rb +875 -0
  107. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +15 -1
  108. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +201 -0
  109. data/spec/mongoid/criteria_spec.rb +3 -0
  110. data/spec/mongoid/encryptable_spec.rb +61 -0
  111. data/spec/mongoid/errors/config_redactor_spec.rb +112 -0
  112. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +31 -0
  113. data/spec/mongoid/errors/no_client_database_spec.rb +29 -0
  114. data/spec/mongoid/errors/no_client_hosts_spec.rb +26 -0
  115. data/spec/mongoid/errors/readonly_association_spec.rb +34 -0
  116. data/spec/mongoid/extensions/vector_spec.rb +175 -0
  117. data/spec/mongoid/matcher/regexp_budget_spec.rb +570 -0
  118. data/spec/mongoid/search_indexable_spec.rb +295 -9
  119. data/spec/mongoid/tasks/database_spec.rb +18 -0
  120. data/spec/mongoid/timestamps/timeless_spec.rb +197 -5
  121. data/spec/mongoid/touchable_spec.rb +25 -0
  122. data/spec/mongoid/touchable_spec_models.rb +10 -0
  123. data/spec/mongoid/validatable/associated_spec.rb +19 -0
  124. data/spec/spec_helper.rb +5 -1
  125. data/spec/support/crypt/models.rb +157 -0
  126. metadata +52 -2
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # BSON::Vector only exists in bson-ruby >= 5.1, so the model and all examples
6
+ # are guarded by min_bson_version. The describe argument is a string (not the
7
+ # constant) so this file loads cleanly on older bson versions.
8
+ if defined?(BSON::Vector)
9
+ class VectorEmbedding
10
+ include Mongoid::Document
11
+
12
+ field :embedding, type: BSON::Vector
13
+ end
14
+ end
15
+
16
+ describe 'BSON::Vector field type' do
17
+ min_bson_version '5.1'
18
+
19
+ shared_examples 'a vector round-trip' do
20
+ let(:vector) do
21
+ BSON::Vector.new(values, dtype, padding)
22
+ end
23
+
24
+ let(:binary) do
25
+ BSON::Binary.from_vector(vector)
26
+ end
27
+
28
+ describe '.mongoize' do
29
+ it 'returns the matching vector binary' do
30
+ expect(BSON::Vector.mongoize(vector)).to eq(binary)
31
+ expect(BSON::Vector.mongoize(vector).type).to eq(:vector)
32
+ end
33
+ end
34
+
35
+ describe '.demongoize' do
36
+ let(:demongoized) do
37
+ BSON::Vector.demongoize(binary)
38
+ end
39
+
40
+ it 'preserves the values, dtype and padding' do
41
+ expect(demongoized).to be_a(BSON::Vector)
42
+ expect(demongoized.to_a).to eq(values)
43
+ expect(demongoized.dtype).to eq(dtype)
44
+ expect(demongoized.padding).to eq(padding)
45
+ end
46
+ end
47
+
48
+ context 'when used as a field type' do
49
+ let!(:model) do
50
+ VectorEmbedding.create!(embedding: vector)
51
+ end
52
+
53
+ let(:reloaded) do
54
+ VectorEmbedding.find(model._id)
55
+ end
56
+
57
+ it 'stores the value as a vector binary' do
58
+ stored = VectorEmbedding.collection.find(_id: model._id).first['embedding']
59
+ expect(stored).to be_a(BSON::Binary)
60
+ expect(stored.type).to eq(:vector)
61
+ end
62
+
63
+ it 'reads the value back as an equivalent BSON::Vector' do
64
+ expect(reloaded.embedding).to be_a(BSON::Vector)
65
+ expect(reloaded.embedding.to_a).to eq(values)
66
+ expect(reloaded.embedding.dtype).to eq(dtype)
67
+ expect(reloaded.embedding.padding).to eq(padding)
68
+ end
69
+ end
70
+ end
71
+
72
+ context 'with an int8 vector' do
73
+ let(:values) { [ 1, 2, 3 ] }
74
+ let(:dtype) { :int8 }
75
+ let(:padding) { 0 }
76
+
77
+ it_behaves_like 'a vector round-trip'
78
+ end
79
+
80
+ context 'with a float32 vector' do
81
+ let(:values) { [ 1.5, -2.0, 0.25 ] }
82
+ let(:dtype) { :float32 }
83
+ let(:padding) { 0 }
84
+
85
+ it_behaves_like 'a vector round-trip'
86
+ end
87
+
88
+ context 'with a packed_bit vector' do
89
+ let(:values) { [ 255, 0, 128 ] }
90
+ let(:dtype) { :packed_bit }
91
+ let(:padding) { 3 }
92
+
93
+ it_behaves_like 'a vector round-trip'
94
+ end
95
+
96
+ describe '#mongoize' do
97
+ let(:vector) do
98
+ BSON::Vector.new([ 1, 2, 3 ], :int8)
99
+ end
100
+
101
+ it 'delegates to the class method and returns a vector binary' do
102
+ expect(vector.mongoize).to eq(BSON::Binary.from_vector(vector))
103
+ expect(vector.mongoize.type).to eq(:vector)
104
+ end
105
+
106
+ # Regression guard: BSON::Vector < ::Array, and Array has its own Mongoid
107
+ # extension. Without our override the value would be mongoized as a plain
108
+ # array, losing the vector subtype.
109
+ it 'does not mongoize via the Array extension' do
110
+ expect(vector.mongoize).to be_a(BSON::Binary)
111
+ expect(vector.mongoize).not_to be_a(Array)
112
+ end
113
+ end
114
+
115
+ describe '.mongoize' do
116
+ let(:vector) do
117
+ BSON::Vector.new([ 1, 2, 3 ], :int8)
118
+ end
119
+
120
+ context 'when given a vector BSON::Binary' do
121
+ it 'returns it unchanged' do
122
+ binary = BSON::Binary.from_vector(vector)
123
+ expect(BSON::Vector.mongoize(binary)).to eq(binary)
124
+ end
125
+ end
126
+
127
+ context 'when given nil' do
128
+ it 'returns nil' do
129
+ expect(BSON::Vector.mongoize(nil)).to be_nil
130
+ end
131
+ end
132
+
133
+ context 'when given a plain array' do
134
+ it 'returns nil' do
135
+ expect(BSON::Vector.mongoize([ 1, 2, 3 ])).to be_nil
136
+ end
137
+ end
138
+
139
+ context 'when given an uncastable type' do
140
+ it 'returns nil' do
141
+ expect(BSON::Vector.mongoize(true)).to be_nil
142
+ end
143
+ end
144
+ end
145
+
146
+ describe '.demongoize' do
147
+ let(:vector) do
148
+ BSON::Vector.new([ 1, 2, 3 ], :int8)
149
+ end
150
+
151
+ context 'when given a BSON::Vector' do
152
+ it 'returns it unchanged' do
153
+ expect(BSON::Vector.demongoize(vector)).to eq(vector)
154
+ end
155
+ end
156
+
157
+ context 'when given a non-vector BSON::Binary' do
158
+ it 'returns nil' do
159
+ expect(BSON::Vector.demongoize(BSON::Binary.new('x', :generic))).to be_nil
160
+ end
161
+ end
162
+
163
+ context 'when given nil' do
164
+ it 'returns nil' do
165
+ expect(BSON::Vector.demongoize(nil)).to be_nil
166
+ end
167
+ end
168
+
169
+ context 'when given an uncastable type' do
170
+ it 'returns nil' do
171
+ expect(BSON::Vector.demongoize(true)).to be_nil
172
+ end
173
+ end
174
+ end
175
+ end